aboutsummaryrefslogtreecommitdiff
path: root/src/progman.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/progman.c')
-rw-r--r--src/progman.c95
1 files changed, 85 insertions, 10 deletions
diff --git a/src/progman.c b/src/progman.c
index da5a970..52c875f 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -952,7 +952,6 @@ check_connection_rate (struct prog *prog)
return 0;
}
-
static int
prog_open_socket (struct prog *prog)
{
@@ -1473,7 +1472,6 @@ progman_create_sockets ()
progman_foreach (prog_create_socket, NULL);
}
-
void
progman_recompute_alarm ()
{
@@ -1508,9 +1506,7 @@ progman_recompute_alarm ()
if (alarm_time)
alarm (alarm_time);
}
-
-
void
progman_start ()
{
@@ -2315,6 +2311,7 @@ progman_cleanup (int expect_term)
{
case TYPE_COMPONENT:
print_status (prog_tag (prog), pid, status, expect_term);
+ prog->v.p.stop = 0;
if (prog->v.p.comp->mode == pies_comp_inetd)
{
struct prog *listener = prog->v.p.listener;
@@ -2418,6 +2415,7 @@ progman_stop_component (struct prog **progptr)
prog_deactivate_listener (prog);
/* fall through */
case status_stopped:
+ prog->v.p.stop = 0;
if (!component_is_active (prog->v.p.comp))
destroy_prog (progptr);
break;
@@ -2425,14 +2423,20 @@ progman_stop_component (struct prog **progptr)
case status_sleeping:
if (!component_is_active (prog->v.p.comp))
destroy_prog (progptr);
+ else if (prog->v.p.stop)
+ prog->v.p.stop = 0;
else
{
logmsg (LOG_INFO, _("waking up component `%s'"), prog_tag (prog));
prog->v.p.failcount = 0;
}
break;
+
+ case status_stopping:
+ break;
- default:
+ case status_finished:
+ prog->v.p.stop = 0;
if (!component_is_active (prog->v.p.comp))
destroy_prog (progptr);
else
@@ -2442,7 +2446,7 @@ progman_stop_component (struct prog **progptr)
}
}
}
-
+
void
prog_deactivate_listener (struct prog *prog)
{
@@ -2478,12 +2482,83 @@ prog_activate_listener (struct prog *prog)
}
return 0;
}
+
+/* Starting at PROG, find first program component marked for termination. */
+static struct prog *
+prog_to_stop (struct prog *prog)
+{
+ for (; prog; prog = prog->next)
+ if (IS_COMPONENT (prog) && prog->v.p.stop)
+ break;
+ return prog;
+}
+
+#define DIAG_CON \
+ (init_process ? (DIAG_TO_STDERR|DIAG_REOPEN_LOG) : diag_output)
+/* Stop all program components marked for termination. Wait at most
+ 2*shutdown_timeout seconds. */
void
-progman_stop_tag (const char *name)
+progman_gc ()
{
- struct prog *prog = progman_locate (name);
- progman_stop_component (&prog);
-}
+ time_t start;
+ struct prog *prog, *next;
+
+ /* Find first marked prog */
+ prog = prog_to_stop (proghead);
+ if (!prog)
+ return;
+
+ /* First round: */
+ /* Gracefully stop it and all marked programs that follow */
+ diagmsg (DIAG_CON, LOG_INFO, "Sending processes the TERM signal");
+ start = time (NULL);
+ do
+ {
+ next = prog->next;
+ progman_stop_component (&prog);
+ }
+ while ((prog = prog_to_stop (next)));
+
+ /* Wait for them to terminate */
+ while (1)
+ {
+ progman_cleanup (1);
+ prog = prog_to_stop (proghead);
+ if (!prog)
+ return;
+ if (time (NULL) - start < shutdown_timeout)
+ sleep (1);
+ else
+ break;
+ }
+
+ /* Second round: */
+ /* Kill the remaining programs with SIGKILL */
+ diagmsg (DIAG_CON, LOG_INFO, "Sending processes the KILL signal");
+ start = time (NULL);
+ do
+ {
+ next = prog->next;
+ prog_stop (prog, SIGKILL);
+ }
+ while ((prog = prog_to_stop (next)));
+ /* Wait for them to terminate */
+ while (1)
+ {
+ progman_cleanup (1);
+ prog = prog_to_stop (proghead);
+ if (!prog)
+ return;
+ if (time (NULL) - start < shutdown_timeout)
+ sleep (1);
+ else
+ break;
+ }
+
+ /* FIXME: Report remaining programs */
+
+}
+
/* EOF */

Return to:

Send suggestions and report system problems to the System administrator.