Ver Fonte

feat: CoreStatus新增互斥锁

SongZihuan há 3 anos atrás
pai
commit
45e36a28d8
5 ficheiros alterados com 40 adições e 16 exclusões
  1. 2 1
      src/core/__env.h
  2. 24 10
      src/core/env.c
  3. 5 3
      src/core/object.c
  4. 8 1
      src/core/run.c
  5. 1 1
      src/core/var.c

+ 2 - 1
src/core/__env.h

@@ -221,6 +221,7 @@ struct af_Environment {  // 运行环境
         core_stop,  // 当前运算退出
         core_exit,  // 解释器退出
     } status;
+    pthread_mutex_t status_lock;
 
     /* 保护空间 */
     struct af_VarSpace *protect;  // 顶级保护变量空间
@@ -279,7 +280,7 @@ struct af_ImportInfo {
 /* Core 管理函数 */
 AFUN_CORE_NO_EXPORT void GcCountAdd1(af_Environment *env);
 AFUN_CORE_NO_EXPORT void GcCountToZero(af_Environment *env);
-
+AFUN_CORE_NO_EXPORT enum af_CoreStatus getCoreStatus(af_Environment *env);
 
 /* 运行时Activity设置函数 (新增Activity) */
 AFUN_CORE_NO_EXPORT bool pushExecutionActivity(af_Code *bt, bool return_first, af_Environment *env);

+ 24 - 10
src/core/env.c

@@ -150,12 +150,16 @@ af_Object *getBaseObject(char *name, af_Environment *env) {
 }
 
 void setCoreStop(af_Environment *env) {
+    pthread_mutex_lock(&env->status_lock);
     if (env->status != core_exit)
         env->status = core_stop;
+    pthread_mutex_unlock(&env->status_lock);
 }
 
 void setCoreExit(int exit_code, af_Environment *env) {
+    pthread_mutex_lock(&env->status_lock);
     env->status = core_exit;
+    pthread_mutex_unlock(&env->status_lock);
 
     pthread_rwlock_wrlock(&env->esv->lock);
     env->exit_code_->num = exit_code;
@@ -163,13 +167,14 @@ void setCoreExit(int exit_code, af_Environment *env) {
 }
 
 void setCoreNormal(af_Environment *env) {
-    if (env->status == core_exit || env->status == core_stop) {
+    pthread_mutex_lock(&env->status_lock);
+    if (env->status == core_exit || env->status == core_stop)
         env->status = core_normal;
+    pthread_mutex_unlock(&env->status_lock);
 
-        pthread_rwlock_wrlock(&env->esv->lock);
-        env->exit_code_->num = 0;
-        pthread_rwlock_unlock(&env->esv->lock);
-    }
+    pthread_rwlock_wrlock(&env->esv->lock);
+    env->exit_code_->num = 0;
+    pthread_rwlock_unlock(&env->esv->lock);
 }
 
 static af_Activity *makeActivity(af_Message *msg_up, af_VarSpaceListNode *varlist, af_Object *belong) {
@@ -2142,9 +2147,10 @@ af_VarSpaceListNode *getRunVarSpaceList(af_Environment *env) {
 }
 
 int isCoreExit(af_Environment *env) {
-    if (env->status == core_exit)
+    enum af_CoreStatus status = getCoreStatus(env);
+    if (status == core_exit)
         return 1;
-    else if (env->status == core_stop)
+    else if (status == core_stop)
         return -1;
     return 0;
 }
@@ -2178,6 +2184,13 @@ size_t getEnviromentSonCount(af_Environment *env) {
     return res;
 }
 
+enum af_CoreStatus getCoreStatus(af_Environment *env) {
+    pthread_mutex_lock(&env->status_lock);
+    enum af_CoreStatus res = env->status;
+    pthread_mutex_unlock(&env->status_lock);
+    return res;
+}
+
 /**
  * 线程外部 指示线程结束
  * @param env
@@ -2196,9 +2209,8 @@ bool isEnviromentExit(af_Environment *env) {
     if (res)
         return true;
 
-    pthread_mutex_lock(&base->thread_lock);
-    res = base->status == core_exit || base->status == core_normal_gc;  // 主线程结束
-    pthread_mutex_unlock(&base->thread_lock);
+    enum af_CoreStatus status = getCoreStatus(base);
+    res = status == core_exit || status == core_normal_gc;  // 主线程结束
     return res;
 }
 
@@ -2207,7 +2219,9 @@ bool isEnviromentExit(af_Environment *env) {
  * @param env
  */
 void waitForEnviromentExit(af_Environment *env) {
+    pthread_mutex_lock(&env->status_lock);
     env->status = core_exit;  // 不需要设置 exit_code
+    pthread_mutex_unlock(&env->status_lock);
 
     while (1) {
         pthread_mutex_lock(&env->thread_lock);

+ 5 - 3
src/core/object.c

@@ -71,6 +71,8 @@ static af_Object *makeObject_Pri(char *id, bool free_api, af_ObjectAPI *api, boo
  */
 af_Object *makeObject(char *id, bool free_api, af_ObjectAPI *api, bool allow_inherit, af_Object *belong,
                       bool free_inherit, af_Inherit *inherit, af_Environment *env){
+    enum af_CoreStatus status = getCoreStatus(env);
+
     if (api == NULL) {
         api = makeObjectAPI();
         free_api = true;
@@ -83,16 +85,16 @@ af_Object *makeObject(char *id, bool free_api, af_ObjectAPI *api, bool allow_inh
         free_inherit = true;
         if (env->global != NULL)
             ih = makeInherit(env->global);
-        else if (env->status != core_creat)
+        else if (status != core_creat)
             return NULL;
     }
 
     if (belong == NULL) {
         if (env->activity != NULL)
             belong = env->activity->belong;
-        else if (env->status == core_init)  // init模式生成: global
+        else if (status == core_init)  // init模式生成: global
             belong = env->global;
-        else if (env->status != core_creat)  // 只有creat可以使用belong=NULL
+        else if (status != core_creat)  // 只有creat可以使用belong=NULL
             return NULL;
     }
 

+ 8 - 1
src/core/run.c

@@ -106,7 +106,10 @@ static bool iterCodeInit(af_Code *code, int mode, af_Environment *env) {
         return false;
     }
 
+    pthread_mutex_lock(&env->status_lock);
     env->status = core_normal_gc;
+    pthread_mutex_unlock(&env->status_lock);
+
     switch (mode) {
         case 0:
             if (env->activity->type != act_top || !codeSemanticCheck(code))
@@ -332,7 +335,8 @@ static bool checkGetArgEnd(af_Message *msg, af_Environment *env) {
 }
 
 static bool checkStop(af_Environment *env) {
-    if (env->status == core_stop || env->status == core_exit) {
+    enum af_CoreStatus status = getCoreStatus(env);
+    if (status == core_stop || status == core_exit) {
         while (env->activity->type != act_top || env->activity->prev != NULL)
             popActivity(false, NULL, env);  // is_normal=false, 非正常退出, 释放mark
         popActivity(false, NULL, env);  // 再释放 act_top
@@ -510,6 +514,9 @@ bool iterDestruct(int deep, af_Environment *env) {
         if (!iterCode(NULL, 3, env))
             return false;
     }
+
+    pthread_mutex_lock(&env->status_lock);
     env->status = core_exit;
+    pthread_mutex_unlock(&env->status_lock);
     return false;
 }

+ 1 - 1
src/core/var.c

@@ -125,7 +125,7 @@ static void freeAllVarCup(af_VarCup *vp) {
 }
 
 af_VarSpace *makeVarSpace(af_Object *belong, char p_self, char p_posterity, char p_external, af_Environment *env){
-    if (env->status != core_creat && belong == NULL)
+    if (getCoreStatus(env) != core_creat && belong == NULL)
         return NULL;
 
     af_VarSpace *vs = calloc(1, sizeof(af_VarSpace));