@@ -130,21 +130,23 @@ impl Zombies {
130
130
self . block . notify_complete ( ) ;
131
131
}
132
132
133
- fn waitpid ( & self , pid : usize , status : & mut u32 ) -> SignalResult < usize > {
133
+ fn waitpid ( & self , pids : & [ usize ] , status : & mut u32 ) -> SignalResult < usize > {
134
134
let mut captured = ( TaskId ( 0 ) , 0 ) ;
135
135
136
136
self . block . block_on ( & self . list , |l| {
137
137
let mut cursor = l. front_mut ( ) ;
138
138
139
139
while let Some ( t) = cursor. get ( ) {
140
- if t. pid ( ) . as_usize ( ) == pid {
141
- captured = ( t. pid ( ) , t. exit_status ( ) ) ;
142
- cursor. remove ( ) ;
140
+ for pid in pids {
141
+ if t. pid ( ) . as_usize ( ) == * pid {
142
+ captured = ( t. pid ( ) , t. exit_status ( ) ) ;
143
+ cursor. remove ( ) ;
143
144
144
- return true ;
145
- } else {
146
- cursor. move_next ( ) ;
145
+ return true ;
146
+ }
147
147
}
148
+
149
+ cursor. move_next ( ) ;
148
150
}
149
151
150
152
false
@@ -344,7 +346,7 @@ impl Task {
344
346
}
345
347
346
348
fn remove_child ( & self , child : & Task ) {
347
- let mut children = self . children . lock ( ) ;
349
+ let mut children = self . children . lock_irq ( ) ;
348
350
349
351
if child. clink . is_linked ( ) {
350
352
let mut cursor = unsafe { children. cursor_mut_from_ptr ( child) } ;
@@ -355,7 +357,7 @@ impl Task {
355
357
}
356
358
357
359
fn add_child ( & self , child : Arc < Task > ) {
358
- let mut children = self . children . lock ( ) ;
360
+ let mut children = self . children . lock_irq ( ) ;
359
361
360
362
child. set_parent ( Some ( self . this ( ) ) ) ;
361
363
children. push_back ( child) ;
@@ -373,8 +375,25 @@ impl Task {
373
375
self . sleep_duration . load ( Ordering :: SeqCst )
374
376
}
375
377
376
- pub fn waitpid ( & self , pid : usize , status : & mut u32 ) -> SignalResult < usize > {
377
- self . zombies . waitpid ( pid, status)
378
+ pub fn waitpid ( & self , pid : isize , status : & mut u32 ) -> SignalResult < usize > {
379
+ if pid == -1 {
380
+ // wait for any child process if no specific process is requested.
381
+ //
382
+ // NOTE: we collect all of the zombie list's process IDs instead of the children
383
+ // list since the child could have been removed from the children list and become a zombie
384
+ // before the parent had a chance to wait for it.
385
+ let pids = self
386
+ . zombies
387
+ . list
388
+ . lock_irq ( )
389
+ . iter ( )
390
+ . map ( |e| e. pid ( ) . as_usize ( ) )
391
+ . collect :: < alloc:: vec:: Vec < _ > > ( ) ;
392
+
393
+ self . zombies . waitpid ( & pids, status)
394
+ } else {
395
+ self . zombies . waitpid ( & [ pid as _ ] , status)
396
+ }
378
397
}
379
398
380
399
pub fn path ( & self ) -> Option < String > {
0 commit comments