Commit 49cfe2dd authored by Guido van Rossum's avatar Guido van Rossum

Fix waiting for children -- save ppid in pidlist as well.

parent f3307389
...@@ -49,7 +49,10 @@ static int do_exit; /* indicates that the program is to exit */ ...@@ -49,7 +49,10 @@ static int do_exit; /* indicates that the program is to exit */
#endif #endif
static int exiting; /* we're already exiting (for maybe_exit) */ static int exiting; /* we're already exiting (for maybe_exit) */
static pid_t my_pid; /* PID of main thread */ static pid_t my_pid; /* PID of main thread */
static pid_t pidlist[MAXPROC]; /* PIDs of other threads */ static struct pidlist {
pid_t parent;
pid_t child;
} pidlist[MAXPROC]; /* PIDs of other threads; protected by count_lock */
static int maxpidindex; /* # of PIDs in pidlist */ static int maxpidindex; /* # of PIDs in pidlist */
#ifndef NO_EXIT_PROG #ifndef NO_EXIT_PROG
...@@ -156,24 +159,36 @@ static void _init_thread _P0() ...@@ -156,24 +159,36 @@ static void _init_thread _P0()
static void clean_threads _P0() static void clean_threads _P0()
{ {
int i; int i, j;
pid_t pid; pid_t mypid, pid;
/* clean up any exited threads */ /* clean up any exited threads */
mypid = getpid();
i = 0; i = 0;
while (i < maxpidindex) { while (i < maxpidindex) {
if ((pid = pidlist[i]) > 0) { if (pidlist[i].parent == mypid && (pid = pidlist[i].child) > 0) {
pid = waitpid(pid, 0, WNOHANG); pid = waitpid(pid, 0, WNOHANG);
if (pid < 0) if (pid > 0) {
return;
if (pid != 0) {
/* a thread has exited */ /* a thread has exited */
pidlist[i] = pidlist[--maxpidindex]; pidlist[i] = pidlist[--maxpidindex];
/* remove references to children of dead proc */
for (j = 0; j < maxpidindex; j++)
if (pidlist[j].parent == pid)
pidlist[j].child = -1;
continue; /* don't increment i */ continue; /* don't increment i */
} }
} }
i++; i++;
} }
/* clean up the list */
i = 0;
while (i < maxpidindex) {
if (pidlist[i].child == -1) {
pidlist[i] = pidlist[--maxpidindex];
continue; /* don't increment i */
}
i++;
}
} }
int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg) int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg)
...@@ -202,9 +217,11 @@ int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg) ...@@ -202,9 +217,11 @@ int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg)
if (usconfig(CONF_INITSIZE, size) < 0) if (usconfig(CONF_INITSIZE, size) < 0)
perror("usconfig - CONF_INITSIZE (reset)"); perror("usconfig - CONF_INITSIZE (reset)");
addr = (long) dl_getrange(size + HDR_SIZE); addr = (long) dl_getrange(size + HDR_SIZE);
dprintf(("trying to use addr %lx-%lx for sproc\n", addr, addr+size)); dprintf(("trying to use addr %lx-%lx for sproc\n",
addr, addr+size));
errno = 0; errno = 0;
if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 && errno != 0) if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 &&
errno != 0)
perror("usconfig - CONF_ATTACHADDR (set)"); perror("usconfig - CONF_ATTACHADDR (set)");
} }
#endif /* USE_DL */ #endif /* USE_DL */
...@@ -213,15 +230,18 @@ int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg) ...@@ -213,15 +230,18 @@ int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg)
perror("sproc"); perror("sproc");
#ifdef USE_DL #ifdef USE_DL
if (!local_initialized) { if (!local_initialized) {
if (usconfig(CONF_ATTACHADDR, addr) < 0) /* reset address */ if (usconfig(CONF_ATTACHADDR, addr) < 0)
/* reset address */
perror("usconfig - CONF_ATTACHADDR (reset)"); perror("usconfig - CONF_ATTACHADDR (reset)");
local_initialized = 1; local_initialized = 1;
} }
#endif /* USE_DL */ #endif /* USE_DL */
if (success >= 0) { if (success >= 0) {
nthreads++; nthreads++;
pidlist[maxpidindex++] = success; pidlist[maxpidindex].parent = getpid();
dprintf(("pidlist[%d] = %d\n", maxpidindex-1, success)); pidlist[maxpidindex++].child = success;
dprintf(("pidlist[%d] = %d\n",
maxpidindex-1, success));
} }
} }
if (usunsetlock(count_lock) < 0) if (usunsetlock(count_lock) < 0)
...@@ -257,8 +277,8 @@ static void do_exit_thread _P1(no_cleanup, int no_cleanup) ...@@ -257,8 +277,8 @@ static void do_exit_thread _P1(no_cleanup, int no_cleanup)
if (nthreads >= 0) { if (nthreads >= 0) {
dprintf(("kill other threads\n")); dprintf(("kill other threads\n"));
for (i = 0; i < maxpidindex; i++) for (i = 0; i < maxpidindex; i++)
if (pidlist[i] > 0) if (pidlist[i].child > 0)
(void) kill(pidlist[i], (void) kill(pidlist[i].child,
SIGKILL); SIGKILL);
_exit(exit_status); _exit(exit_status);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment