Преглед изворни кода

ncd: use jobs instead of direct iteration when initializing processes and when initiating their shutdown.
This allows a module to do its job work before NCD does something with another module, and allows modules not to be independent.
Otherwise, if modules were not independent, problems would arise when a job event between a module and NCD is scheduled but not yet delivered, and another module
causes an internal event at the module.

ambrop7 пре 15 година
родитељ
комит
f7e4dff34a
1 измењених фајлова са 69 додато и 13 уклоњено
  1. 69 13
      ncd/ncd.c

+ 69 - 13
ncd/ncd.c

@@ -127,6 +127,18 @@ struct NCDConfig_interfaces *configuration;
 // processes
 // processes
 LinkedList2 processes;
 LinkedList2 processes;
 
 
+// job for initializing processes
+BPending init_job;
+
+// next process for init job
+struct NCDConfig_interfaces *init_next;
+
+// job for initiating shutdown of processes
+BPending free_job;
+
+// process iterator for free job
+LinkedList2Iterator free_it;
+
 static void terminate (void);
 static void terminate (void);
 static void print_help (const char *name);
 static void print_help (const char *name);
 static void print_version (void);
 static void print_version (void);
@@ -151,6 +163,8 @@ static void process_statement_log (struct process_statement *ps, int level, cons
 static void process_statement_set_error (struct process_statement *ps);
 static void process_statement_set_error (struct process_statement *ps);
 static void process_statement_instance_handler_event (struct process_statement *ps, int event);
 static void process_statement_instance_handler_event (struct process_statement *ps, int event);
 static void process_statement_instance_handler_died (struct process_statement *ps, int is_error);
 static void process_statement_instance_handler_died (struct process_statement *ps, int is_error);
+static void init_job_handler (void *unused);
+static void free_job_handler (void *unused);
 
 
 int main (int argc, char **argv)
 int main (int argc, char **argv)
 {
 {
@@ -264,12 +278,15 @@ int main (int argc, char **argv)
     // init processes list
     // init processes list
     LinkedList2_Init(&processes);
     LinkedList2_Init(&processes);
     
     
-    // init processes
-    struct NCDConfig_interfaces *pc = configuration;
-    while (pc) {
-        process_new(pc);
-        pc = pc->next;
-    }
+    // init init job
+    BPending_Init(&init_job, BReactor_PendingGroup(&ss), init_job_handler, NULL);
+    
+    // init free job
+    BPending_Init(&free_job, BReactor_PendingGroup(&ss), free_job_handler, NULL);
+    
+    // start initializing processes
+    init_next = configuration;
+    BPending_Set(&init_job);
     
     
     // enter event loop
     // enter event loop
     BLog(BLOG_NOTICE, "entering event loop");
     BLog(BLOG_NOTICE, "entering event loop");
@@ -281,6 +298,12 @@ int main (int argc, char **argv)
         struct process *p = UPPER_OBJECT(n, struct process, list_node);
         struct process *p = UPPER_OBJECT(n, struct process, list_node);
         process_free(p);
         process_free(p);
     }
     }
+    
+    // free free job
+    BPending_Free(&free_job);
+    
+    // free init job
+    BPending_Free(&init_job);
 fail5:
 fail5:
     // free configuration
     // free configuration
     NCDConfig_free_interfaces(configuration);
     NCDConfig_free_interfaces(configuration);
@@ -317,13 +340,9 @@ void terminate (void)
         return;
         return;
     }
     }
     
     
-    LinkedList2Iterator it;
-    LinkedList2Iterator_InitForward(&it, &processes);
-    LinkedList2Node *n;
-    while (n = LinkedList2Iterator_Next(&it)) {
-        struct process *p = UPPER_OBJECT(n, struct process, list_node);
-        process_work(p);
-    }
+    // start free job
+    LinkedList2Iterator_InitForward(&free_it, &processes);
+    BPending_Set(&free_job);
 }
 }
 
 
 void print_help (const char *name)
 void print_help (const char *name)
@@ -1052,3 +1071,40 @@ void process_statement_instance_handler_died (struct process_statement *ps, int
     process_work(p);
     process_work(p);
     return;
     return;
 }
 }
+
+void init_job_handler (void *unused)
+{
+    ASSERT(!terminating)
+    
+    if (!init_next) {
+        // initialized all processes
+        return;
+    }
+    
+    struct NCDConfig_interfaces *conf = init_next;
+    
+    // schedule next
+    init_next = init_next->next;
+    BPending_Set(&init_job);
+    
+    // init process
+    process_new(conf);
+}
+
+void free_job_handler (void *unused)
+{
+    ASSERT(terminating)
+    
+    LinkedList2Node *n = LinkedList2Iterator_Next(&free_it);
+    if (!n) {
+        // done initiating shutdown for all processes
+        return;
+    }
+    struct process *p = UPPER_OBJECT(n, struct process, list_node);
+    
+    // schedule next
+    BPending_Set(&free_job);
+    
+    process_work(p);
+    return;
+}