From 72bee1679b5c43a044b52c13fcdb79f58eacfbcf Mon Sep 17 00:00:00 2001 From: obarun <eric@obarun.org> Date: Mon, 14 Mar 2022 11:00:26 +1100 Subject: [PATCH] starts the tree process after the dependencies are ready. Need to implement a communication between processes to wait for real state of a dependency --- src/lib66/exec/ssexec_all.c | 105 +++++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 37 deletions(-) diff --git a/src/lib66/exec/ssexec_all.c b/src/lib66/exec/ssexec_all.c index fbcfb9b3..6ce109e6 100644 --- a/src/lib66/exec/ssexec_all.c +++ b/src/lib66/exec/ssexec_all.c @@ -51,12 +51,11 @@ #define FLAGS_STOPPING 2 // stopping not really down #define FLAGS_UP 3 // really up #define FLAGS_DOWN 4 // really down -/* #define FLAGS_BLOCK 5 // all deps are not up/down #define FLAGS_UNBLOCK 6 // all deps up/down #define FLAGS_FATAL 7 // process crashed #define FLAGS_EXITED 8 // process exited -*/ + /** return 1 if set, else 0*/ #define FLAGS_ISSET(has, want) \ @@ -73,6 +72,7 @@ struct pidvertex_s } ; #define PIDINDEX_ZERO { 0, 0, 0, 0, 0 } +//static pidvertex_t *apidvertex ; static pidvertex_t *apidvertex ; static unsigned int napid = 0 ; static unsigned int npid = 0 ; @@ -182,9 +182,15 @@ static int doit(ssexec_t *info, char const *treename, unsigned int what) } else { log_warn ("uninitialized tree: ", info->treename.s) ; - goto freed ; + goto end ; } } + /** tree can be empty + * In this case ssexec_init do not crash but the + * /run/66/state/<owner>/<treename> doesn't exit. + * So check it again */ + if (!tree_isinitialized(info->base.s, info->treename.s)) + goto end ; if (what == 2) { @@ -240,7 +246,7 @@ static int doit(ssexec_t *info, char const *treename, unsigned int what) stralloc_free(&salist) ; } - freed: + end: e = 0 ; err: return e ; @@ -374,25 +380,25 @@ static void pidvertex_init_array(pidvertex_t *apidvertex, graph_t *g, unsigned i } -static void pidvertex_array_free(pidvertex_t *apidvertex, unsigned int len) +static void pidvertex_array_free(pidvertex_t *apidv, unsigned int len) { log_flow() ; size_t pos = 0 ; for(; pos < len ; pos++) - pidvertex_free(&apidvertex[pos]) ; + pidvertex_free(&apidv[pos]) ; } -static int pidvertex_get_id(pidvertex_t *apidvertex, unsigned int id) +static int pidvertex_get_id(pidvertex_t *apidv, unsigned int id) { log_flow() ; unsigned int pos = 0 ; for (; pos < napid ; pos++) { - if (apidvertex[pos].vertex == id) + if (apidv[pos].vertex == id) return (unsigned int) pos ; } return -1 ; @@ -403,14 +409,17 @@ static void async_deps(unsigned int i, unsigned int what, ssexec_t *info, graph_ log_flow() ; unsigned int pos = 0 ; + while (apidvertex[i].nedge) { /** TODO: the pidvertex_get_id() function make a loop * through the apidvertex array to find the corresponding * index of the edge at the apidvertex array. * This is clearly a waste of time and need to be optimized. */ unsigned int id = pidvertex_get_id(apidvertex, apidvertex[i].edge[pos]) ; + if (id < 0) log_dieu(LOG_EXIT_SYS, "get apidvertex id -- please make a bug report") ; + async(id, what, info, graph) ; apidvertex[i].nedge-- ; pos++ ; @@ -429,9 +438,13 @@ static void async(unsigned int i, unsigned int what, ssexec_t *info, graph_t *gr int r ; pid_t pid ; + char *treename = graph->data.s + genalloc_s(graph_hash_t,&graph->hash)[apidvertex[i].vertex].vertex ; - if (FLAGS_ISSET(apidvertex[i].state, flag) || FLAGS_ISSET(apidvertex[i].state, flag_run)) { + if (FLAGS_ISSET(apidvertex[i].state, flag) && !FLAGS_ISSET(apidvertex[i].state, flag_run)) { + + apidvertex[i].state |= flag_run ; + apidvertex[i].state |= FLAGS_BLOCK ; pid = fork() ; @@ -440,29 +453,33 @@ static void async(unsigned int i, unsigned int what, ssexec_t *info, graph_t *gr if (!pid) { - if (!apidvertex[i].nedge) { - /** Mark as processing */ - apidvertex[i].state |= flag_run ; - r = doit(info, treename, what) ; - _exit(r) ; + if (apidvertex[i].nedge) + async_deps(i, what, info, graph) ; - } else { + r = doit(info, treename, what) ; + _exit(r) ; - async_deps(i, what, info, graph) ; - } } - apidvertex[i].pid = pid ; + apidvertex[npid++].pid = pid ; } else { - log_trace("skipping: ", treename, " -- already ", FLAGS_ISSET(flag,FLAGS_DOWN) ? "down" : "up") ; + log_trace("skipping: ", treename, " -- already ", what ? "down" : "up") ; } return ; } -static int handle_signal(pidvertex_t *apidvertex) +static inline void kill_all (void) +{ + log_flow() ; + + unsigned int j = npid ; + while (j--) kill(apidvertex[j].pid, SIGKILL) ; +} + +static int handle_signal(pidvertex_t *apidvertex, unsigned int what) { log_flow() ; @@ -470,7 +487,8 @@ static int handle_signal(pidvertex_t *apidvertex) for (;;) { - switch (selfpipe_read()) { + int s = selfpipe_read() ; + switch (s) { case -1 : log_warnusys_return(LOG_EXIT_ZERO,"selfpipe_read") ; case 0 : return ok ; @@ -497,38 +515,53 @@ static int handle_signal(pidvertex_t *apidvertex) if (j < npid) { + unsigned int i = j ; + apidvertex[j] = apidvertex[--npid] ; if (!WIFSIGNALED(wstat) && !WEXITSTATUS(wstat)) { - apidvertex[j].state &= ~flag & ~flag_run ; + apidvertex[i].state = 0 ; + if (what) + apidvertex[i].state = FLAGS_UP ; + else + apidvertex[i].state = FLAGS_DOWN ; + + apidvertex[i].state |= FLAGS_UNBLOCK ; } else { ok = 0 ; - apidvertex[j].state &= ~flag & ~flag_run ; + apidvertex[i].state = 0 ; + if (what) + apidvertex[i].state = FLAGS_DOWN ; + else + apidvertex[i].state = FLAGS_UP ; } - - apidvertex[j] = apidvertex[--npid] ; } } break ; case SIGTERM : case SIGINT : - log_warn("received SIGINT, aborting service transition") ; + log_info("received SIGINT, aborting service transition") ; + kill_all() ; break ; - default : log_warn("unexpected data in selfpipe") ; + default : log_die(LOG_EXIT_SYS, "unexpected data in selfpipe") ; } } return ok ; } -static int waitit(int spfd, pidvertex_t *apidvertex, graph_t *graph, unsigned int what, tain *deadline, ssexec_t *info) +static int waitit(int spfd, pidvertex_t *apidv, graph_t *graph, unsigned int what, tain *deadline, ssexec_t *info) { iopause_fd x = { .fd = spfd, .events = IOPAUSE_READ } ; unsigned int e = 1, pos = 0 ; int r ; - npid = napid ; + pidvertex_t apidvertextable[napid] ; + apidvertex = apidvertextable ; + + for (; pos < napid ; pos++) + apidvertex[pos] = apidv[pos] ; - for (; pos < npid ; pos++) + for (pos = 0 ; pos < napid ; pos++) async(pos, what, info, graph) ; while (npid) { @@ -538,7 +571,7 @@ static int waitit(int spfd, pidvertex_t *apidvertex, graph_t *graph, unsigned in log_dieusys(LOG_EXIT_SYS, "iopause") ; if (!r) log_die(LOG_EXIT_SYS,"time out") ; - if (!handle_signal(apidvertex)) + if (!handle_signal(apidvertex, what)) e = 0 ; } return e ; @@ -602,8 +635,6 @@ int ssexec_all(int argc, char const *const *argv,char const *const *envp, ssexec pidvertex_t apidv[graph.mlen] ; - apidvertex = apidv ; - /** only on tree */ if (info->treename.len) { @@ -620,7 +651,7 @@ int ssexec_all(int argc, char const *const *argv,char const *const *envp, ssexec alist[napid++] = (unsigned int)graph_hash_vertex_get_id(&graph, info->treename.s) ; - pidvertex_init_array(apidvertex, &graph, alist, napid, info, requiredby) ; + pidvertex_init_array(apidv, &graph, alist, napid, info, requiredby) ; free(alist) ; @@ -628,7 +659,7 @@ int ssexec_all(int argc, char const *const *argv,char const *const *envp, ssexec napid = graph.sort_count ; - pidvertex_init_array(apidvertex, &graph, graph.sort, graph.sort_count, info, requiredby) ; + pidvertex_init_array(apidv, &graph, graph.sort, graph.sort_count, info, requiredby) ; } if (shut) { @@ -672,7 +703,7 @@ int ssexec_all(int argc, char const *const *argv,char const *const *envp, ssexec !selfpipe_trap(SIGTERM)) log_dieusys(LOG_EXIT_SYS, "selfpipe_trap") ; - r = waitit(spfd, apidvertex, &graph, what, &deadline, info) ; + r = waitit(spfd, apidv, &graph, what, &deadline, info) ; end: selfpipe_finish() ; @@ -690,7 +721,7 @@ int ssexec_all(int argc, char const *const *argv,char const *const *envp, ssexec } graph_free_all(&graph) ; - pidvertex_array_free(apidvertex, napid) ; + pidvertex_array_free(apidv, napid) ; return (!r) ? 111 : 0 ; -- GitLab