diff options
-rw-r--r-- | src/progman.c | 102 |
1 files changed, 73 insertions, 29 deletions
diff --git a/src/progman.c b/src/progman.c index 2c38b63..da5a970 100644 --- a/src/progman.c +++ b/src/progman.c @@ -119,27 +119,31 @@ prog_tag (struct prog const *prog) } void -link_prog (struct prog *pp, int prepend) +link_prog (struct prog *prog, struct prog *ref) { - if (prepend) + if (!ref) { + prog->prev = NULL; + prog->next = proghead; if (proghead) - proghead->prev = pp; - pp->prev = NULL; - pp->next = proghead; - proghead = pp; - if (!progtail) - progtail = pp; + proghead->prev = prog; + else + progtail = prog; + proghead = prog; } else { - pp->next = NULL; - pp->prev = progtail; - if (progtail) - progtail->next = pp; + struct prog *x; + + prog->prev = ref; + prog->next = ref->next; + + if ((x = ref->next)) + x->prev = prog; else - proghead = pp; - progtail = pp; + progtail = prog; + + ref->next = prog; } } @@ -217,7 +221,7 @@ register_redir (int type, struct prog *master) pp->type = TYPE_REDIRECTOR; pp->v.r.tag = tag; pp->v.r.master = master; - link_prog (pp, 1); + link_prog (pp, NULL); component_ref_incr (master->v.p.comp); return pp; } @@ -237,6 +241,42 @@ update_redir (int type, struct prog *master, pid_t pid) pp->pid = pid; } +/* Given the component COMP find the element of the program list + after which to link in the new prog associated with that COMP. + The progs in the resulting list must be arranged exactly in the + same order as the corresponding components. Points to note: + 1. If comp->prog is already present, follow progs in its next + chain until the last one that points to the same COMP is found. + 2. Otherwise, if that component is not the first one, step back + to the previous component and do the same for its comp->prog chain. + 3. Return the prog found. +*/ +static struct prog * +find_prog_ref (struct component *comp) +{ + struct prog *prog; + + if (!comp->prog) + { + comp = comp->prev; + if (!comp) + return NULL; /* FIXME: Skip redirectors? */ + } + + if (comp->prog) + { + for (prog = comp->prog; + prog->next + && IS_COMPONENT (prog->next) + && prog->next->v.p.comp == comp; + prog = prog->next) + ; + } + else + prog = NULL; + return prog; +} + static struct prog * register_prog0 (struct component *comp) { @@ -261,8 +301,8 @@ register_prog0 (struct component *comp) if (comp->mode != pies_comp_exec) comp->redir[RETR_OUT].type = redir_null; - - link_prog (newp, 0); + + link_prog (newp, find_prog_ref (comp)); component_ref_incr (comp); return newp; } @@ -281,7 +321,7 @@ register_command (char *tag, char *command, pid_t pid) newp->pid = pid; newp->v.c.tag = grecs_strdup (tag); newp->v.c.command = command; - link_prog (newp, 0); + link_prog (newp, progtail); } int @@ -1405,11 +1445,10 @@ progman_accept (int socket, void *data) static int prog_create_socket (struct prog *prog, void *data) { - if (IS_COMPONENT (prog)) + if (IS_COMPONENT (prog) && prog->v.p.status == status_listener) { struct component *comp = prog->v.p.comp; - if (comp->mode == pies_comp_inetd && !ISCF_TCPMUX (comp->flags) - && prog->v.p.socket == -1) + if (!ISCF_TCPMUX (comp->flags) && prog->v.p.socket == -1) { int fd = create_socket (comp->socket_url, comp->socket_type, @@ -1486,19 +1525,24 @@ progman_start () for (prog = proghead; prog; prog = prog->next) if (IS_COMPONENT (prog)) { - if (prog->v.p.comp->mode == pies_comp_inetd) + switch (prog->v.p.status) { + case status_stopped: + case status_sleeping: + prog_start (prog); + break; + + case status_running: + case status_stopping: + case status_finished: + break; + + case status_listener: if (!prog->v.p.active) disable_socket (prog->v.p.socket); else - { - prog->v.p.status = status_listener; - enable_socket (prog->v.p.socket); - } + enable_socket (prog->v.p.socket); } - else if (prog->v.p.status == status_stopped - || prog->v.p.status == status_sleeping) - prog_start (prog); } } |