@@ -49,7 +49,10 @@ static int do_exit; /* indicates that the program is to exit */
4949#endif
5050static int exiting ; /* we're already exiting (for maybe_exit) */
5151static pid_t my_pid ; /* PID of main thread */
52- static pid_t pidlist [MAXPROC ]; /* PIDs of other threads */
52+ static struct pidlist {
53+ pid_t parent ;
54+ pid_t child ;
55+ } pidlist [MAXPROC ]; /* PIDs of other threads; protected by count_lock */
5356static int maxpidindex ; /* # of PIDs in pidlist */
5457
5558#ifndef NO_EXIT_PROG
@@ -156,24 +159,36 @@ static void _init_thread _P0()
156159
157160static void clean_threads _P0 ()
158161{
159- int i ;
160- pid_t pid ;
162+ int i , j ;
163+ pid_t mypid , pid ;
161164
162165 /* clean up any exited threads */
166+ mypid = getpid ();
163167 i = 0 ;
164168 while (i < maxpidindex ) {
165- if ((pid = pidlist [i ]) > 0 ) {
169+ if (pidlist [ i ]. parent == mypid && (pid = pidlist [i ]. child ) > 0 ) {
166170 pid = waitpid (pid , 0 , WNOHANG );
167- if (pid < 0 )
168- return ;
169- if (pid != 0 ) {
171+ if (pid > 0 ) {
170172 /* a thread has exited */
171173 pidlist [i ] = pidlist [-- maxpidindex ];
174+ /* remove references to children of dead proc */
175+ for (j = 0 ; j < maxpidindex ; j ++ )
176+ if (pidlist [j ].parent == pid )
177+ pidlist [j ].child = -1 ;
172178 continue ; /* don't increment i */
173179 }
174180 }
175181 i ++ ;
176182 }
183+ /* clean up the list */
184+ i = 0 ;
185+ while (i < maxpidindex ) {
186+ if (pidlist [i ].child == -1 ) {
187+ pidlist [i ] = pidlist [-- maxpidindex ];
188+ continue ; /* don't increment i */
189+ }
190+ i ++ ;
191+ }
177192}
178193
179194int 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)
202217 if (usconfig (CONF_INITSIZE , size ) < 0 )
203218 perror ("usconfig - CONF_INITSIZE (reset)" );
204219 addr = (long ) dl_getrange (size + HDR_SIZE );
205- dprintf (("trying to use addr %lx-%lx for sproc\n" , addr , addr + size ));
220+ dprintf (("trying to use addr %lx-%lx for sproc\n" ,
221+ addr , addr + size ));
206222 errno = 0 ;
207- if ((addr = usconfig (CONF_ATTACHADDR , addr )) < 0 && errno != 0 )
223+ if ((addr = usconfig (CONF_ATTACHADDR , addr )) < 0 &&
224+ errno != 0 )
208225 perror ("usconfig - CONF_ATTACHADDR (set)" );
209226 }
210227#endif /* USE_DL */
@@ -213,15 +230,18 @@ int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg)
213230 perror ("sproc" );
214231#ifdef USE_DL
215232 if (!local_initialized ) {
216- if (usconfig (CONF_ATTACHADDR , addr ) < 0 ) /* reset address */
233+ if (usconfig (CONF_ATTACHADDR , addr ) < 0 )
234+ /* reset address */
217235 perror ("usconfig - CONF_ATTACHADDR (reset)" );
218236 local_initialized = 1 ;
219237 }
220238#endif /* USE_DL */
221239 if (success >= 0 ) {
222240 nthreads ++ ;
223- pidlist [maxpidindex ++ ] = success ;
224- dprintf (("pidlist[%d] = %d\n" , maxpidindex - 1 , success ));
241+ pidlist [maxpidindex ].parent = getpid ();
242+ pidlist [maxpidindex ++ ].child = success ;
243+ dprintf (("pidlist[%d] = %d\n" ,
244+ maxpidindex - 1 , success ));
225245 }
226246 }
227247 if (usunsetlock (count_lock ) < 0 )
@@ -257,8 +277,8 @@ static void do_exit_thread _P1(no_cleanup, int no_cleanup)
257277 if (nthreads >= 0 ) {
258278 dprintf (("kill other threads\n" ));
259279 for (i = 0 ; i < maxpidindex ; i ++ )
260- if (pidlist [i ] > 0 )
261- (void ) kill (pidlist [i ],
280+ if (pidlist [i ]. child > 0 )
281+ (void ) kill (pidlist [i ]. child ,
262282 SIGKILL );
263283 _exit (exit_status );
264284 }
0 commit comments