@@ -2,39 +2,84 @@ use alloc::{
22 borrow:: Cow ,
33 sync:: { Arc , Weak } ,
44} ;
5- use core:: task:: Context ;
5+ use core:: {
6+ sync:: atomic:: { AtomicBool , Ordering } ,
7+ task:: Context ,
8+ } ;
69
710use axerrno:: { AxError , AxResult } ;
811use axpoll:: { IoEvents , PollSet , Pollable } ;
912
10- use crate :: { file:: FileLike , task:: ProcessData } ;
13+ use crate :: {
14+ file:: FileLike ,
15+ task:: { ProcessData , Thread } ,
16+ } ;
1117
1218pub struct PidFd {
1319 proc_data : Weak < ProcessData > ,
1420 exit_event : Arc < PollSet > ,
21+ thread_exit : Option < Arc < AtomicBool > > ,
22+
23+ non_blocking : AtomicBool ,
1524}
1625impl PidFd {
17- pub fn new ( proc_data : & Arc < ProcessData > ) -> Self {
26+ pub fn new_process ( proc_data : & Arc < ProcessData > ) -> Self {
1827 Self {
1928 proc_data : Arc :: downgrade ( proc_data) ,
2029 exit_event : proc_data. exit_event . clone ( ) ,
30+ thread_exit : None ,
31+
32+ non_blocking : AtomicBool :: new ( false ) ,
33+ }
34+ }
35+
36+ pub fn new_thread ( thread : & Thread ) -> Self {
37+ Self {
38+ proc_data : Arc :: downgrade ( & thread. proc_data ) ,
39+ exit_event : thread. exit_event . clone ( ) ,
40+ thread_exit : Some ( thread. exit . clone ( ) ) ,
41+
42+ non_blocking : AtomicBool :: new ( false ) ,
2143 }
2244 }
2345
2446 pub fn process_data ( & self ) -> AxResult < Arc < ProcessData > > {
47+ // For threads, the pidfd is invalid once the thread exits, even if its
48+ // process is still alive.
49+ if let Some ( thread_exit) = & self . thread_exit
50+ && thread_exit. load ( Ordering :: Acquire )
51+ {
52+ return Err ( AxError :: NoSuchProcess ) ;
53+ }
2554 self . proc_data . upgrade ( ) . ok_or ( AxError :: NoSuchProcess )
2655 }
2756}
2857impl FileLike for PidFd {
2958 fn path ( & self ) -> Cow < ' _ , str > {
3059 "anon_inode:[pidfd]" . into ( )
3160 }
61+
62+ fn set_nonblocking ( & self , nonblocking : bool ) -> AxResult {
63+ self . non_blocking . store ( nonblocking, Ordering :: Release ) ;
64+ Ok ( ( ) )
65+ }
66+
67+ fn nonblocking ( & self ) -> bool {
68+ self . non_blocking . load ( Ordering :: Acquire )
69+ }
3270}
3371
3472impl Pollable for PidFd {
3573 fn poll ( & self ) -> IoEvents {
3674 let mut events = IoEvents :: empty ( ) ;
37- events. set ( IoEvents :: IN , self . proc_data . strong_count ( ) > 0 ) ;
75+ events. set (
76+ IoEvents :: IN ,
77+ self . proc_data . strong_count ( ) > 0
78+ && self
79+ . thread_exit
80+ . as_ref ( )
81+ . is_none_or ( |it| !it. load ( Ordering :: Acquire ) ) ,
82+ ) ;
3883 events
3984 }
4085
0 commit comments