diff --git a/src/lib66/exec/ssexec_all.c b/src/lib66/exec/ssexec_all.c
index be758090ecac17ec3f0be4bb8fdc171d04cd2572..1a1e257cb80eb125676fd1316d889d666f1d8178 100644
--- a/src/lib66/exec/ssexec_all.c
+++ b/src/lib66/exec/ssexec_all.c
@@ -27,20 +27,61 @@
 #include <oblibs/sastr.h>
 #include <oblibs/obgetopt.h>
 #include <oblibs/files.h>
+#include <oblibs/graph.h>
 
 #include <skalibs/types.h>
 #include <skalibs/stralloc.h>
 #include <skalibs/djbunix.h>
 #include <skalibs/posixplz.h>
+#include <skalibs/tai.h>
+#include <skalibs/selfpipe.h>
+#include <skalibs/iopause.h>
 
 #include <66/ssexec.h>
 #include <66/constants.h>
 #include <66/tree.h>
 #include <66/utils.h>//scandir_ok
 #include <66/db.h>
+#include <66/graph.h>
 
 #include <s6-rc/s6rc-servicedir.h>
 
+
+#define FLAGS_STARTING 1 // starting not really up
+#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) \
+        ((~(has) & (want)) == 0)
+
+typedef struct pidvertex_s pidvertex_t, *pidvertex_t_ref ;
+struct pidvertex_s
+{
+    pid_t pid ;
+    unsigned int vertex ; // id at graph_hash_t struct
+    uint8_t state ;
+    int nedge ;
+    unsigned int *edge ; // array of id at graph_hash_t struct
+} ;
+#define PIDINDEX_ZERO { 0, 0, 0, 0, 0 }
+
+static pidvertex_t *apidvertex ;
+static unsigned int napid = 0 ;
+static unsigned int npid = 0 ;
+static int flag ;
+static int flag_run ;
+
+static void async(unsigned int i, unsigned int what, ssexec_t *info, graph_t *graph) ;
+static int unsupervise(ssexec_t *info, int what) ;
+
 static inline unsigned int lookup (char const *const *table, char const *signal)
 {
     log_flow() ;
@@ -54,113 +95,158 @@ static inline unsigned int parse_signal (char const *signal)
 {
     log_flow() ;
 
-    static char const *const signal_table[] =
-    {
+    static char const *const signal_table[] = {
         "up",
         "down",
         "unsupervise",
         0
     } ;
-  unsigned int i = lookup(signal_table, signal) ;
-  if (!signal_table[i]) log_usage(usage_all) ;
-  return i ;
+    unsigned int i = lookup(signal_table, signal) ;
+    if (!signal_table[i]) log_usage(usage_all) ;
+    return i ;
 }
 
-int all_doit(ssexec_t *info, unsigned int what, char const *const *envp)
+static void redir_fd(void)
 {
     log_flow() ;
 
-    int r ;
+    int fd ;
+    while((fd = open("/dev/tty",O_RDWR|O_NOCTTY)) >= 0) {
 
-    stralloc salist = STRALLOC_ZERO ;
-    char const *exclude[2] = { SS_LIVETREE_INIT, 0 } ;
+        if (fd >= 3)
+            break ;
+    }
 
-    char ownerstr[UID_FMT] ;
-    size_t ownerlen = uid_fmt(ownerstr,info->owner) ;
-    ownerstr[ownerlen] = 0 ;
+    dup2 (fd,0) ;
+    dup2 (fd,1) ;
+    dup2 (fd,2) ;
+    fd_close(fd) ;
 
-    char src[info->live.len + SS_STATE_LEN + 1 + ownerlen + 1 + info->treename.len + 1 + SS_LIVETREE_INIT_LEN + 1] ;
-    auto_strings(src,info->live.s,SS_STATE,"/",ownerstr,"/",info->treename.s,"/",SS_LIVETREE_INIT) ;
+    if (setsid() < 0)
+        log_dieusys(LOG_EXIT_SYS,"setsid") ;
 
-    r = scan_mode(src,S_IFREG) ;
-    if (r == -1) log_die(LOG_EXIT_SYS,src," conflicted format") ;
-    if (!r) {
-        log_warn ("uninitialized tree: ", info->treename.s) ;
-        goto freed ;
-    }
+    if ((chdir("/")) < 0)
+        log_dieusys(LOG_EXIT_SYS,"chdir") ;
+
+    ioctl(0,TIOCSCTTY,1) ;
+
+    umask(022) ;
+}
 
-    src[info->live.len + SS_STATE_LEN + 1 + ownerlen + 1 + info->treename.len] = 0 ;
 
-    if (!sastr_dir_get(&salist,src,exclude,S_IFREG))
-        log_dieusys(LOG_EXIT_SYS,"get contents of directory: ",src) ;
+static int doit(ssexec_t *info, char const *treename, unsigned int what)
+{
+    log_flow() ;
+
+    int r, e = 1 ;
 
-    if (salist.len)
     {
-        size_t pos = 0, len = sastr_len(&salist) ;
-        int n = what == 2 ? 3 : 2 ;
-        int nargc = n + len ;
-        char const *newargv[nargc] ;
-        unsigned int m = 0 ;
+        info->treename.len = 0 ;
 
-        newargv[m++] = "fake_name" ;
-        if (what == 2)
-            newargv[m++] = "-u" ;
+        if (!auto_stra(&info->treename, treename))
+            log_die_nomem("stralloc") ;
 
-        FOREACH_SASTR(&salist,pos) {
+        info->tree.len = 0 ;
 
-            newargv[m++] = salist.s + pos ;
-        }
+        if (!auto_stra(&info->tree, treename))
+            log_die_nomem("stralloc") ;
+
+        r = tree_sethome(info) ;
+        if (r <= 0)
+            log_warnu_return(LOG_EXIT_ONE, "find tree: ", info->treename.s) ;
+
+        if (!tree_get_permissions(info->tree.s, info->owner))
+            log_warn_return(LOG_EXIT_ONE, "You're not allowed to use the tree: ", info->tree.s) ;
+
+    }
 
-        newargv[m++] = 0 ;
+    if (!tree_isinitialized(info->base.s, info->treename.s)) {
 
         if (!what) {
 
-            if (ssexec_start(nargc,newargv,envp,info))
-                goto err ;
+            int nargc = 3 ;
+            char const *newargv[nargc] ;
+            unsigned int m = 0 ;
+
+            newargv[m++] = "fake_name" ;
+            newargv[m++] = "b" ;
+            newargv[m++] = 0 ;
+
+            if (ssexec_init(nargc, newargv, (char const *const *)environ, info))
+                log_warnu_return(LOG_EXIT_ONE, "initiate services of tree: ", info->treename.s) ;
+
+            log_trace("reload scandir: ", info->scandir.s) ;
+            if (scandir_send_signal(info->scandir.s, "h") <= 0)
+                log_warnu_return(LOG_EXIT_ONE, "reload scandir: ", info->scandir.s) ;
 
         } else {
 
-            if (ssexec_stop(nargc,newargv,envp,info))
-                goto err ;
+            log_warn ("uninitialized tree: ", info->treename.s) ;
+            goto freed ;
         }
     }
-    else
-        log_info("Empty tree: ",info->treename.s," -- nothing to do") ;
 
-    freed:
-        stralloc_free(&salist) ;
-        return 1 ;
-    err:
-        stralloc_free(&salist) ;
-        return 0 ;
-}
+    if (what == 2) {
 
-static void all_redir_fd(void)
-{
-    log_flow() ;
+       if (unsupervise(info, what))
+            goto err ;
 
-    int fd ;
-    while((fd = open("/dev/tty",O_RDWR|O_NOCTTY)) >= 0)
-    {
-        if (fd >= 3) break ;
-    }
-    dup2 (fd,0) ;
-    dup2 (fd,1) ;
-    dup2 (fd,2) ;
-    fd_close(fd) ;
+    } else {
 
-    if (setsid() < 0)
-        log_dieusys(LOG_EXIT_SYS,"setsid") ;
+        char const *exclude[1] = { 0 } ;
+        char ownerstr[UID_FMT] ;
+        size_t ownerlen = uid_fmt(ownerstr, info->owner) ;
+        ownerstr[ownerlen] = 0 ;
 
-    if ((chdir("/")) < 0)
-        log_dieusys(LOG_EXIT_SYS,"chdir") ;
+        stralloc salist = STRALLOC_ZERO ;
 
-    ioctl(0,TIOCSCTTY,1) ;
+        char src[info->live.len + SS_STATE_LEN + 1 + ownerlen + 1 + info->treename.len + 1] ;
 
-    umask(022) ;
+        auto_strings(src, info->live.s, SS_STATE, "/", ownerstr, "/", info->treename.s) ;
+
+        if (!sastr_dir_get(&salist, src, exclude, S_IFREG))
+            log_warnusys_return(LOG_EXIT_ONE, "get contents of directory: ", src) ;
+
+        if (salist.len) {
+
+            size_t pos = 0, len = sastr_len(&salist) ;
+            int n = what == 2 ? 3 : 2 ;
+            int nargc = n + len ;
+            char const *newargv[nargc] ;
+            unsigned int m = 0 ;
+
+            newargv[m++] = "fake_name" ;
+            if (what == 2)
+                newargv[m++] = "-u" ;
+
+            FOREACH_SASTR(&salist, pos)
+                newargv[m++] = salist.s + pos ;
+
+            newargv[m++] = 0 ;
+
+            if (!what) {
+
+                if (ssexec_start(nargc, newargv, (char const *const *)environ, info))
+                    goto err ;
+
+            } else {
+
+                if (ssexec_stop(nargc, newargv, (char const *const *)environ, info))
+                    goto err ;
+            }
+
+        } else log_info("Empty tree: ", info->treename.s, " -- nothing to do") ;
+
+        stralloc_free(&salist) ;
+    }
+
+    freed:
+        e = 0 ;
+    err:
+        return e ;
 }
 
-void all_unsupervise(ssexec_t *info, char const *const *envp,int what)
+static int unsupervise(ssexec_t *info, int what)
 {
     log_flow() ;
 
@@ -168,75 +254,305 @@ void all_unsupervise(ssexec_t *info, char const *const *envp,int what)
     char const *exclude[1] = { 0 } ;
 
     char ownerstr[UID_FMT] ;
-    size_t ownerlen = uid_fmt(ownerstr,info->owner) ;
+    size_t ownerlen = uid_fmt(ownerstr, info->owner) ;
     ownerstr[ownerlen] = 0 ;
 
     stralloc salist = STRALLOC_ZERO ;
 
     /** set what we need */
     char prefix[info->treename.len + 2] ;
-    auto_strings(prefix,info->treename.s,"-") ;
+    auto_strings(prefix, info->treename.s, "-") ;
 
     char livestate[info->live.len + SS_STATE_LEN + 1 + ownerlen + 1 + info->treename.len + 1] ;
-    auto_strings(livestate,info->live.s,SS_STATE + 1,"/",ownerstr,"/",info->treename.s) ;
+    auto_strings(livestate, info->live.s, SS_STATE + 1, "/", ownerstr, "/", info->treename.s) ;
 
     /** bring down service */
-    if (!all_doit(info,what,envp))
+    if (all_doit(info, info->treename.s, what))
         log_warnusys("stop services") ;
 
-    if (db_find_compiled_state(info->livetree.s,info->treename.s) >=0)
-    {
+    if (db_find_compiled_state(info->livetree.s, info->treename.s) >=0) {
+
         salist.len = 0 ;
         char livetree[newlen + info->treename.len + SS_SVDIRS_LEN + 1] ;
-        auto_strings(livetree,info->livetree.s,"/",info->treename.s,SS_SVDIRS) ;
+        auto_strings(livetree, info->livetree.s, "/", info->treename.s, SS_SVDIRS) ;
 
-        if (!sastr_dir_get(&salist,livetree,exclude,S_IFDIR)) log_dieusys(LOG_EXIT_SYS,"get service list at: ",livetree) ;
+        if (!sastr_dir_get(&salist,livetree,exclude,S_IFDIR))
+            log_warnusys_return(LOG_EXIT_ONE, "get service list at: ", livetree) ;
 
         livetree[newlen + info->treename.len] = 0 ;
 
         pos = 0 ;
         FOREACH_SASTR(&salist,pos) {
 
-            s6rc_servicedir_unsupervise(livetree,prefix,salist.s + pos,0) ;
+            s6rc_servicedir_unsupervise(livetree, prefix, salist.s + pos, 0) ;
         }
 
         char *realsym = realpath(livetree, 0) ;
         if (!realsym)
-            log_dieusys(LOG_EXIT_SYS,"find realpath of: ",livetree) ;
+            log_warnusys_return(LOG_EXIT_ONE, "find realpath of: ", livetree) ;
 
         if (rm_rf(realsym) == -1)
-            log_dieusys(LOG_EXIT_SYS,"remove: ", realsym) ;
+            log_warnusys_return(LOG_EXIT_ONE, "remove: ", realsym) ;
 
         free(realsym) ;
 
         if (rm_rf(livetree) == -1)
-            log_dieusys(LOG_EXIT_SYS,"remove: ", livetree) ;
+            log_warnusys_return(LOG_EXIT_ONE, "remove: ", livetree) ;
 
         /** remove the symlink itself */
         unlink_void(livetree) ;
     }
 
     if (scandir_send_signal(info->scandir.s,"h") <= 0)
-        log_dieusys(LOG_EXIT_SYS,"reload scandir: ",info->scandir.s) ;
+        log_warnusys_return(LOG_EXIT_ONE, "reload scandir: ", info->scandir.s) ;
 
     /** remove /run/66/state/uid/treename directory */
-    log_trace("delete: ",livestate,"..." ) ;
+    log_trace("delete: ", livestate, "..." ) ;
     if (rm_rf(livestate) < 0)
-        log_dieusys(LOG_EXIT_SYS,"delete ",livestate) ;
+        log_warnusys_return(LOG_EXIT_ONE, "delete ", livestate) ;
 
-    log_info("Unsupervised successfully tree: ",info->treename.s) ;
+    log_info("Unsupervised successfully tree: ", info->treename.s) ;
 
     stralloc_free(&salist) ;
+
+    return 0 ;
 }
 
-int ssexec_all(int argc, char const *const *argv,char const *const *envp,ssexec_t *info)
+static pidvertex_t pidvertex_init(unsigned int len)
 {
+    log_flow() ;
+
+    pidvertex_t pidv = PIDINDEX_ZERO ;
+
+    pidv.edge = (unsigned int *)malloc(len*sizeof(unsigned int)) ;
+
+    graph_array_init_single(pidv.edge, len) ;
+
+    return pidv ;
+}
+
+static void pidvertex_free(pidvertex_t *pidv)
+{
+    free(pidv->edge) ;
+}
+
+static void pidvertex_init_array(pidvertex_t *apidvertex, graph_t *g, unsigned int *list, unsigned int count, ssexec_t *info, uint8_t requiredby)
+{
+    log_flow() ;
+
+    int r = -1 ;
+    size_t pos = 0 ;
+
+    for (; pos < count ; pos++) {
+
+        char *name = g->data.s + genalloc_s(graph_hash_t,&g->hash)[list[pos]].vertex ;
+
+        pidvertex_t pidv = pidvertex_init(g->mlen) ;
 
-    int r, what, shut = 0, fd ;
+        pidv.nedge = graph_matrix_get_edge_g_sorted_list(pidv.edge, g, name, requiredby) ;
 
-    size_t statesize, pos = 0 ;
+        if (pidv.nedge < 0)
+            log_dieu(LOG_EXIT_SYS,"get sorted ", requiredby ? "required by" : "dependency", " list of tree: ", name) ;
 
-    stralloc contents = STRALLOC_ZERO ;
+        pidv.vertex = list[pos] ;
+
+        if (pidv.vertex < 0)
+            log_dieu(LOG_EXIT_SYS, "get vertex id -- please make a bug report") ;
+
+        r = tree_isinitialized(info->base.s, name) ;
+
+        if (r < 0)
+            log_dieu(LOG_EXIT_SYS, "read resolve file of tree: ", name) ;
+
+        if (r)
+            pidv.state |= FLAGS_UP ;
+        else
+            pidv.state |= FLAGS_DOWN ;
+
+        apidvertex[pos] = pidv ;
+    }
+
+}
+
+static void pidvertex_array_free(pidvertex_t *apidvertex,  unsigned int len)
+{
+    log_flow() ;
+
+    size_t pos = 0 ;
+
+    for(; pos < len ; pos++)
+        pidvertex_free(&apidvertex[pos]) ;
+
+}
+
+static int pidvertex_get_id(pidvertex_t *apidvertex, unsigned int id)
+{
+    log_flow() ;
+
+    unsigned int pos = 0 ;
+
+    for (; pos < napid ; pos++) {
+        if (apidvertex[pos].vertex == id)
+            return (unsigned int) pos ;
+    }
+    return -1 ;
+}
+
+static void async_deps(unsigned int i, unsigned int what, ssexec_t *info, graph_t *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++ ;
+    }
+
+
+}
+
+static void async(unsigned int i, unsigned int what, ssexec_t *info, graph_t *graph)
+{
+    /**
+     * @i: apidvertex array index
+     * */
+
+    log_flow() ;
+
+    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)) {
+
+        pid = fork() ;
+
+        if (pid < 0)
+            log_dieusys(LOG_EXIT_SYS, "fork") ;
+
+        if (!pid) {
+
+            if (!apidvertex[i].nedge) {
+                /** Mark as processing */
+                apidvertex[i].state |= flag_run ;
+                r = doit(info, treename, what) ;
+                _exit(r) ;
+
+            } else {
+
+                async_deps(i, what, info, graph) ;
+            }
+        }
+
+        apidvertex[i].pid = pid ;
+
+     } else {
+
+         log_trace("skipping: ", treename, " -- already ", FLAGS_ISSET(flag,FLAGS_DOWN) ? "down" : "up") ;
+     }
+
+    return ;
+}
+
+static int handle_signal(pidvertex_t *apidvertex)
+{
+    log_flow() ;
+
+    int ok = 1 ;
+
+    for (;;) {
+
+        switch (selfpipe_read()) {
+
+            case -1 : log_warnusys_return(LOG_EXIT_ZERO,"selfpipe_read") ;
+            case 0 : return ok ;
+            case SIGCHLD :
+
+                for (;;) {
+
+                    unsigned int j = 0 ;
+                    int wstat ;
+                    pid_t r = wait_nohang(&wstat) ;
+
+                    if (r < 0) {
+
+                        if (errno = ECHILD)
+                            break ;
+                        else
+                            log_dieusys(LOG_EXIT_SYS,"wait for children") ;
+
+                    } else if (!r) break ;
+
+                    for (; j < npid ; j++)
+                        if (apidvertex[j].pid == r)
+                            break ;
+
+                    if (j < npid) {
+
+                        if (!WIFSIGNALED(wstat) && !WEXITSTATUS(wstat)) {
+
+                             apidvertex[j].state &= ~flag & ~flag_run ;
+
+                        } else {
+
+                            ok = 0 ;
+                            apidvertex[j].state &= ~flag & ~flag_run ;
+                        }
+
+                        apidvertex[j] = apidvertex[--npid] ;
+                    }
+                }
+                break ;
+            case SIGTERM :
+            case SIGINT :
+                    log_warn("received SIGINT, aborting service transition") ;
+                    break ;
+            default : log_warn("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)
+{
+    iopause_fd x = { .fd = spfd, .events = IOPAUSE_READ } ;
+    unsigned int e = 1, pos = 0 ;
+    int r ;
+    npid = napid ;
+
+    for (; pos < npid ; pos++)
+        async(pos, what, info, graph) ;
+
+    while (npid) {
+
+        r = iopause_g(&x, 1, deadline) ;
+        if (r < 0)
+            log_dieusys(LOG_EXIT_SYS, "iopause") ;
+        if (!r)
+            log_die(LOG_EXIT_SYS,"time out") ;
+        if (!handle_signal(apidvertex))
+            e = 0 ;
+    }
+    return e ;
+}
+
+int ssexec_all(int argc, char const *const *argv,char const *const *envp, ssexec_t *info)
+{
+
+    int r, shut = 0, fd ;
+    tain deadline ;
+    unsigned int what ;
+
+    uint8_t requiredby = 0 ;
+    graph_t graph = GRAPH_ZERO ;
 
     {
         subgetopt l = SUBGETOPT_ZERO ;
@@ -257,148 +573,125 @@ int ssexec_all(int argc, char const *const *argv,char const *const *envp,ssexec_
 
     if (argc != 1) log_usage(usage_all) ;
 
+    if (info->timeout)
+        tain_from_millisecs(&deadline, info->timeout) ;
+    else
+        deadline = tain_infinite_relative ;
+
     what = parse_signal(*argv) ;
 
-    if ((scandir_ok(info->scandir.s)) <= 0)
-        log_die(LOG_EXIT_SYS,"scandir: ", info->scandir.s," is not running") ;
+    if (what) {
 
-    char ste[info->base.len + SS_SYSTEM_LEN + SS_STATE_LEN + 1] ;
-    auto_strings(ste,info->base.s,SS_SYSTEM,SS_STATE) ;
+        requiredby = 1 ;
+        flag =  FLAGS_UP ;
+        flag_run = FLAGS_STOPPING ;
 
-    r = scan_mode(ste,S_IFREG) ;
-    if (r < 0) log_die(LOG_EXIT_SYS,"conflict format for: ",ste) ;
-    if (!r) log_dieusys(LOG_EXIT_SYS,"find: ",ste) ;
+    } else {
 
-    /** only one tree?*/
-    if (info->treename.len)
-    {
-        if (!auto_stra(&contents,info->treename.s))
-            log_die_nomem("stralloc") ;
+        flag = FLAGS_DOWN ;
+        flag_run = FLAGS_STARTING ;
     }
-    else
-    {
-        statesize = file_get_size(ste) ;
 
-        r = openreadfileclose(ste,&contents,statesize) ;
-        if(!r) log_dieusys(LOG_EXIT_SYS,"open: ", ste) ;
+    if ((scandir_ok(info->scandir.s)) <= 0)
+        log_die(LOG_EXIT_SYS,"scandir: ", info->scandir.s," is not running") ;
 
-        /** ensure that we have an empty line at the end of the string*/
-        if (!stralloc_cats(&contents,"\n") ||
-        !stralloc_0(&contents)) log_die_nomem("stralloc") ;
+    if (!graph_build_g(&graph, info->base.s, info->treename.s, DATA_TREE))
+        log_dieu(LOG_EXIT_SYS,"build the graph") ;
 
-        if (!sastr_clean_element(&contents)) {
-            log_info("nothing to do") ;
-            goto end ;
-        }
+    /** initialize and allocate apidvertex array */
 
-    }
+    pidvertex_t apidv[graph.mlen] ;
 
-    if (shut)
-    {
-        pid_t dpid ;
-        int wstat = 0 ;
+    apidvertex = apidv ;
 
-        dpid = fork() ;
+    /** only on tree */
+    if (info->treename.len) {
 
-        if (dpid < 0) log_dieusys(LOG_EXIT_SYS,"fork") ;
-        else if (dpid > 0)
-        {
-            if (waitpid_nointr(dpid,&wstat, 0) < 0)
-                log_dieusys(LOG_EXIT_SYS,"wait for child") ;
+        unsigned int *alist ;
 
-            if (wstat)
-                log_die(LOG_EXIT_SYS,"child fail") ;
+        alist = (unsigned int *)malloc(graph.mlen*sizeof(unsigned int)) ;
 
-            goto end ;
-        }
-        else all_redir_fd() ;
-    }
+        graph_array_init_single(alist, graph.mlen) ;
 
-    /** Down/unsupervise process? reverse in that case to respect tree start order*/
-    if (what)
-        if (!sastr_reverse(&contents)) log_dieu(LOG_EXIT_SYS,"reserve tree order") ;
+        napid = graph_matrix_get_edge_g_sorted_list(alist, &graph, info->treename.s, requiredby) ;
 
-    FOREACH_SASTR(&contents,pos) {
+        if (napid < 0)
+            log_dieu(LOG_EXIT_SYS, "get ", requiredby ? "required" : "dependencies", " sorted list of: ", info->treename.s) ;
 
-        info->treename.len = 0 ;
+        alist[napid++] = (unsigned int)graph_hash_vertex_get_id(&graph, info->treename.s) ;
 
-        if (!auto_stra(&info->treename,contents.s + pos))
-            log_die_nomem("stralloc") ;
+        pidvertex_init_array(apidvertex, &graph, alist, napid, info, requiredby) ;
 
-        info->tree.len = 0 ;
+        free(alist) ;
 
-        if (!auto_stra(&info->tree,contents.s + pos))
-            log_die_nomem("stralloc") ;
-        /**
-         *
-         *
-         *
-         *
-         *
-         *
-         *
-         * Attention ici avec le nouveau format de tree_sethome()
-         *
-         *
-         *
-         *
-         *
-         *
-         *
-         *
-         *
-         *
-         *
-         *
-         * */
-        r = tree_sethome(info) ;
-        if (r <= 0) log_dieusys(LOG_EXIT_SYS,"find tree: ", info->treename.s) ;
+    } else {
 
-        if (!tree_get_permissions(info->tree.s,info->owner))
-            log_die(LOG_EXIT_USER,"You're not allowed to use the tree: ",info->tree.s) ;
+        napid = graph.sort_count ;
 
-        if (!what)
-        {
-            int nargc = 3 ;
-            char const *newargv[nargc] ;
-            unsigned int m = 0 ;
+        pidvertex_init_array(apidvertex, &graph, graph.sort, graph.sort_count, info, requiredby) ;
+    }
 
-            newargv[m++] = "fake_name" ;
-            newargv[m++] = "b" ;
-            newargv[m++] = 0 ;
+    if (shut) {
+
+        pid_t pid ;
+        int wstat = 0 ;
 
-            if (ssexec_init(nargc,newargv,envp,info))
-                log_dieu(LOG_EXIT_SYS,"initiate services of tree: ",info->treename.s) ;
+        pid = fork() ;
 
-            log_trace("reload scandir: ",info->scandir.s) ;
-            if (scandir_send_signal(info->scandir.s,"h") <= 0)
-                log_dieusys(LOG_EXIT_SYS,"reload scandir: ",info->scandir.s) ;
-        }
+        if (pid < 0)
+            log_dieusys(LOG_EXIT_SYS,"fork") ;
 
-        if (what < 2) {
+        if (!pid) {
 
-            if (!all_doit(info,what,envp))
-                log_dieu(LOG_EXIT_SYS,(what) ? "start" : "stop" , " services of tree: ",info->treename.s) ;
+            redir_fd() ;
 
         } else {
 
-            all_unsupervise(info,envp,what) ;
+            if (waitpid_nointr(pid,&wstat, 0) < 0)
+                log_dieusys(LOG_EXIT_SYS,"wait for child") ;
+
+            if (wstat)
+                log_die(LOG_EXIT_SYS,"child fail") ;
+
+            r = 1 ;
+
+            goto end ;
         }
     }
+
+    tain_now_set_stopwatch_g() ;
+    tain_add_g(&deadline, &deadline) ;
+
+    int spfd = selfpipe_init() ;
+
+    if (spfd < 0)
+        log_dieusys(LOG_EXIT_SYS, "selfpipe_init") ;
+
+    if (!selfpipe_trap(SIGCHLD) ||
+        !selfpipe_trap(SIGINT) ||
+        !selfpipe_trap(SIGTERM))
+            log_dieusys(LOG_EXIT_SYS, "selfpipe_trap") ;
+
+    r = waitit(spfd, apidvertex, &graph, what, &deadline, info) ;
+
     end:
-        if (shut)
-        {
+        selfpipe_finish() ;
+
+        if (shut) {
+
             while((fd = open("/dev/tty",O_RDWR|O_NOCTTY)) >= 0)
-            {
-                if (fd >= 3) break ;
-            }
+                if (fd >= 3)
+                    break ;
+
             dup2 (fd,0) ;
             dup2 (fd,1) ;
             dup2 (fd,2) ;
             fd_close(fd) ;
         }
 
-        stralloc_free(&contents) ;
+        graph_free_all(&graph) ;
+        pidvertex_array_free(apidvertex, napid) ;
 
-    return 0 ;
+
+    return (!r) ? 111 : 0 ;
 }