@@ -1401,34 +1401,35 @@ process_add_sigchld_handler (void)
1401
1401
void
1402
1402
mono_w32process_signal_finished (void )
1403
1403
{
1404
- int status ;
1405
- int pid ;
1406
- Process * process ;
1404
+ mono_coop_mutex_lock (& processes_mutex );
1405
+
1406
+ for (Process * process = processes ; process ; process = process -> next ) {
1407
+ int status = -1 ;
1408
+ int pid ;
1407
1409
1408
- do {
1409
1410
do {
1410
- pid = waitpid (-1 , & status , WNOHANG );
1411
+ pid = waitpid (process -> pid , & status , WNOHANG );
1411
1412
} while (pid == -1 && errno == EINTR );
1412
1413
1413
- if (pid <= 0 )
1414
- break ;
1415
-
1416
- mono_coop_mutex_lock (& processes_mutex );
1414
+ // possible values of 'pid':
1415
+ // process->pid : the status changed for this child
1416
+ // 0 : status unchanged for this PID
1417
+ // ECHILD : process has been reaped elsewhere (or never existed)
1418
+ // EINVAL : invalid PID or other argument
1417
1419
1418
- for (process = processes ; process ; process = process -> next ) {
1419
- if (process -> pid != pid )
1420
- continue ;
1421
- if (process -> signalled )
1422
- continue ;
1420
+ // Therefore, we ignore status unchanged (nothing to do) and error
1421
+ // events (process is cleaned up later).
1422
+ if (pid <= 0 )
1423
+ continue ;
1424
+ if (process -> signalled )
1425
+ continue ;
1423
1426
1424
- process -> signalled = TRUE;
1425
- process -> status = status ;
1426
- mono_coop_sem_post (& process -> exit_sem );
1427
- break ;
1428
- }
1427
+ process -> signalled = TRUE;
1428
+ process -> status = status ;
1429
+ mono_coop_sem_post (& process -> exit_sem );
1430
+ }
1429
1431
1430
- mono_coop_mutex_unlock (& processes_mutex );
1431
- } while (1 );
1432
+ mono_coop_mutex_unlock (& processes_mutex );
1432
1433
}
1433
1434
1434
1435
static gboolean
0 commit comments