Browse Source

ncd: NCDModule: make interpreter-side process functions call the process creator callbacks directly, and remove a bunch ofstates made redundant

ambrop7 13 năm trước cách đây
mục cha
commit
d95c751389
3 tập tin đã thay đổi với 47 bổ sung84 xóa
  1. 17 68
      ncd/NCDModule.c
  2. 3 1
      ncd/NCDModule.h
  3. 27 15
      ncd/ncd.c

+ 17 - 68
ncd/NCDModule.c

@@ -46,13 +46,9 @@
 
 #define PROCESS_STATE_INIT 1
 #define PROCESS_STATE_DOWN 2
-#define PROCESS_STATE_UP_PENDING 3
 #define PROCESS_STATE_UP 4
-#define PROCESS_STATE_DOWN_PENDING 5
 #define PROCESS_STATE_DOWN_WAITING 6
-#define PROCESS_STATE_DOWN_CONTINUE_PENDING 7
 #define PROCESS_STATE_TERMINATING 8
-#define PROCESS_STATE_TERMINATED_PENDING 9
 #define PROCESS_STATE_TERMINATED 10
 
 static int object_func_getvar (NCDModuleInst *n, const char *name, NCDValMem *mem, NCDValRef *out_value);
@@ -65,42 +61,6 @@ static void frontend_event (NCDModuleInst *n, int event)
     n->params->func_event(n->user, event);
 }
 
-static void process_event_job_handler (NCDModuleProcess *o)
-{
-    DebugObject_Access(&o->d_obj);
-    
-    switch (o->state) {
-        case PROCESS_STATE_DOWN_CONTINUE_PENDING: {
-            o->state = PROCESS_STATE_DOWN;
-            
-            o->interp_func_event(o->interp_user, NCDMODULEPROCESS_INTERP_EVENT_CONTINUE);
-        } break;
-        
-        case PROCESS_STATE_UP_PENDING: {
-            o->state = PROCESS_STATE_UP;
-            
-            o->handler_event(o->user, NCDMODULEPROCESS_EVENT_UP);
-            return;
-        } break;
-        
-        case PROCESS_STATE_DOWN_PENDING: {
-            o->state = PROCESS_STATE_DOWN_WAITING;
-            
-            o->handler_event(o->user, NCDMODULEPROCESS_EVENT_DOWN);
-            return;
-        } break;
-        
-        case PROCESS_STATE_TERMINATED_PENDING: {
-            o->state = PROCESS_STATE_TERMINATED;
-            
-            o->handler_event(o->user, NCDMODULEPROCESS_EVENT_TERMINATED);
-            return;
-        } break;
-        
-        default: ASSERT(0);
-    }
-}
-
 static void inst_assert_backend (NCDModuleInst *n)
 {
     ASSERT(n->state == STATE_DOWN_UNCLEAN || n->state == STATE_DOWN_CLEAN ||
@@ -380,9 +340,6 @@ int NCDModuleProcess_Init (NCDModuleProcess *o, NCDModuleInst *n, const char *te
     // set no special functions
     o->func_getspecialobj = NULL;
     
-    // init event job
-    BPending_Init(&o->event_job, BReactor_PendingGroup(n->iparams->reactor), (BPending_handler)process_event_job_handler, o);
-    
     // set state
     o->state = PROCESS_STATE_INIT;
     
@@ -405,7 +362,6 @@ int NCDModuleProcess_Init (NCDModuleProcess *o, NCDModuleInst *n, const char *te
     return 1;
     
 fail1:
-    BPending_Free(&o->event_job);
     return 0;
 }
 
@@ -413,9 +369,6 @@ void NCDModuleProcess_Free (NCDModuleProcess *o)
 {
     DebugObject_Free(&o->d_obj);
     ASSERT(o->state == PROCESS_STATE_TERMINATED)
-    
-    // free event job
-    BPending_Free(&o->event_job);
 }
 
 void NCDModuleProcess_AssertFree (NCDModuleProcess *o)
@@ -444,11 +397,9 @@ void NCDModuleProcess_Continue (NCDModuleProcess *o)
 void NCDModuleProcess_Terminate (NCDModuleProcess *o)
 {
     DebugObject_Access(&o->d_obj);
-    ASSERT(o->state == PROCESS_STATE_DOWN || o->state == PROCESS_STATE_UP_PENDING ||
-           o->state == PROCESS_STATE_DOWN_CONTINUE_PENDING || o->state == PROCESS_STATE_UP ||
-           o->state == PROCESS_STATE_DOWN_PENDING || o->state == PROCESS_STATE_DOWN_WAITING)
+    ASSERT(o->state == PROCESS_STATE_DOWN || o->state == PROCESS_STATE_UP ||
+           o->state == PROCESS_STATE_DOWN_WAITING)
     
-    BPending_Unset(&o->event_job);
     o->state = PROCESS_STATE_TERMINATING;
     
     o->interp_func_event(o->interp_user, NCDMODULEPROCESS_INTERP_EVENT_TERMINATE);
@@ -462,7 +413,7 @@ int NCDModuleProcess_GetObj (NCDModuleProcess *o, const char *name, NCDObject *o
     ASSERT(out_object)
     
     // interpreter gone?
-    if (o->state == PROCESS_STATE_TERMINATED_PENDING || o->state == PROCESS_STATE_TERMINATED) {
+    if (o->state == PROCESS_STATE_TERMINATED) {
         return 0;
     }
     
@@ -475,10 +426,8 @@ int NCDModuleProcess_GetObj (NCDModuleProcess *o, const char *name, NCDObject *o
 static void process_assert_interp (NCDModuleProcess *o)
 {
     // assert that the interpreter knows about the object, and we're not in init
-    ASSERT(o->state == PROCESS_STATE_DOWN || o->state == PROCESS_STATE_UP_PENDING ||
-           o->state == PROCESS_STATE_DOWN_CONTINUE_PENDING || o->state == PROCESS_STATE_UP ||
-           o->state == PROCESS_STATE_DOWN_PENDING || o->state == PROCESS_STATE_DOWN_WAITING ||
-           o->state == PROCESS_STATE_TERMINATING)
+    ASSERT(o->state == PROCESS_STATE_DOWN || o->state == PROCESS_STATE_UP ||
+           o->state == PROCESS_STATE_DOWN_WAITING || o->state == PROCESS_STATE_TERMINATING)
 }
 
 void NCDModuleProcess_Interp_SetHandlers (NCDModuleProcess *o, void *interp_user,
@@ -500,8 +449,10 @@ void NCDModuleProcess_Interp_Up (NCDModuleProcess *o)
     process_assert_interp(o);
     ASSERT(o->state == PROCESS_STATE_DOWN)
     
-    BPending_Set(&o->event_job);
-    o->state = PROCESS_STATE_UP_PENDING;
+    o->state = PROCESS_STATE_UP;
+    
+    o->handler_event(o->user, NCDMODULEPROCESS_EVENT_UP);
+    return;
 }
 
 void NCDModuleProcess_Interp_Down (NCDModuleProcess *o)
@@ -510,15 +461,11 @@ void NCDModuleProcess_Interp_Down (NCDModuleProcess *o)
     process_assert_interp(o);
     
     switch (o->state) {
-        case PROCESS_STATE_UP_PENDING: {
-            BPending_Unset(&o->event_job);
-            BPending_Set(&o->event_job);
-            o->state = PROCESS_STATE_DOWN_CONTINUE_PENDING;
-        } break;
-        
         case PROCESS_STATE_UP: {
-            BPending_Set(&o->event_job);
-            o->state = PROCESS_STATE_DOWN_PENDING;
+            o->state = PROCESS_STATE_DOWN_WAITING;
+            
+            o->handler_event(o->user, NCDMODULEPROCESS_EVENT_DOWN);
+            return;
         } break;
         
         default: ASSERT(0);
@@ -531,8 +478,10 @@ void NCDModuleProcess_Interp_Terminated (NCDModuleProcess *o)
     process_assert_interp(o);
     ASSERT(o->state == PROCESS_STATE_TERMINATING)
     
-    BPending_Set(&o->event_job);
-    o->state = PROCESS_STATE_TERMINATED_PENDING;
+    o->state = PROCESS_STATE_TERMINATED;
+    
+    o->handler_event(o->user, NCDMODULEPROCESS_EVENT_TERMINATED);
+    return;
 }
 
 int NCDModuleProcess_Interp_GetSpecialObj (NCDModuleProcess *o, const char *name, NCDObject *out_object)

+ 3 - 1
ncd/NCDModule.h

@@ -310,7 +310,6 @@ typedef struct NCDModuleProcess_s {
     void *user;
     NCDModuleProcess_handler_event handler_event;
     NCDModuleProcess_func_getspecialobj func_getspecialobj;
-    BPending event_job;
     int state;
     void *interp_user;
     NCDModuleProcess_interp_func_event interp_func_event;
@@ -585,6 +584,7 @@ void NCDModuleProcess_Interp_SetHandlers (NCDModuleProcess *o, void *interp_user
  * Reports the process backend as up.
  * The process backend must be in down state.
  * The process backend enters up state.
+ * WARNING: this directly calls the process creator; expect to be called back
  * 
  * @param o process backend handle
  */
@@ -594,6 +594,7 @@ void NCDModuleProcess_Interp_Up (NCDModuleProcess *o);
  * Reports the process backend as down.
  * The process backend must be in up state.
  * The process backend enters waiting state.
+ * WARNING: this directly calls the process creator; expect to be called back
  * 
  * NOTE: the backend enters waiting state, NOT down state. The interpreter should
  * pause the process until {@link NCDModuleProcess_interp_func_event} reports
@@ -609,6 +610,7 @@ void NCDModuleProcess_Interp_Down (NCDModuleProcess *o);
  * The process backend must be in terminating state.
  * The process backend handle becomes invalid and must not be used
  * by the interpreter any longer.
+ * WARNING: this directly calls the process creator; expect to be called back
  * 
  * @param o process backend handle
  */

+ 27 - 15
ncd/ncd.c

@@ -156,7 +156,7 @@ static int parse_arguments (int argc, char *argv[]);
 static void signal_handler (void *unused);
 static void start_terminate (int exit_code);
 static int process_new (NCDProcess *proc_ast, NCDInterpBlock *iblock, NCDModuleProcess *module_process);
-static void process_free (struct process *p);
+static void process_free (struct process *p, NCDModuleProcess **out_mp);
 static int process_mem_is_preallocated (struct process *p, char *mem);
 static void process_start_terminating (struct process *p);
 static int process_rap (struct process *p);
@@ -381,7 +381,9 @@ fail6:;
     LinkedList1Node *ln;
     while (ln = LinkedList1_GetFirst(&processes)) {
         struct process *p = UPPER_OBJECT(ln, struct process, list_node);
-        process_free(p);
+        NCDModuleProcess *mp;
+        process_free(p, &mp);
+        ASSERT(!mp)
     }
 fail5:
     // free modules
@@ -708,15 +710,14 @@ fail0:
     return 0;
 }
 
-void process_free (struct process *p)
+void process_free (struct process *p, NCDModuleProcess **out_mp)
 {
     ASSERT(p->ap == 0)
     ASSERT(p->fp == 0)
+    ASSERT(out_mp)
     
-    // inform module process that the process is terminated
-    if (p->module_process) {
-        NCDModuleProcess_Interp_Terminated(p->module_process);
-    }
+    // give module process to caller so it can inform the process creator that the process has terminated
+    *out_mp = p->module_process;
     
     // free statement memory
     for (int i = 0; i < p->num_statements; i++) {
@@ -829,13 +830,23 @@ void process_work_job_handler (struct process *p)
     
     if (p->state == PSTATE_TERMINATING) {
         if (p->fp == 0) {
-            // finished retreating
-            process_free(p);
+            // free process
+            NCDModuleProcess *mp;
+            process_free(p, &mp);
             
             // if program is terminating amd there are no more processes, exit program
             if (terminating && LinkedList1_IsEmpty(&processes)) {
+                ASSERT(!mp)
                 BReactor_Quit(&reactor, 0);
+                return;
             }
+            
+            // inform the process creator that the process has terminated
+            if (mp) {
+                NCDModuleProcess_Interp_Terminated(mp);
+                return;
+            }
+            
             return;
         }
         
@@ -864,11 +875,11 @@ void process_work_job_handler (struct process *p)
     if (p->state == PSTATE_UP && !(p->ap == process_rap(p) && p->ap == p->num_statements)) {
         // if we have module process, wait for its permission to continue
         if (p->module_process) {
-            // set module process down
-            NCDModuleProcess_Interp_Down(p->module_process);
-            
             // set state waiting
             p->state = PSTATE_WAITING;
+            
+            // set module process down
+            NCDModuleProcess_Interp_Down(p->module_process);
             return;
         }
         
@@ -933,13 +944,14 @@ void process_work_job_handler (struct process *p)
     if (p->state == PSTATE_WORKING) {
         process_log(p, BLOG_INFO, "victory");
         
+        // set state up
+        p->state = PSTATE_UP;
+        
         // set module process up
         if (p->module_process) {
             NCDModuleProcess_Interp_Up(p->module_process);
+            return;
         }
-        
-        // set state up
-        p->state = PSTATE_UP;
     }
 }