1
1
use std:: fmt;
2
2
use std:: sync:: { Arc , Mutex } ;
3
+ use std:: os:: raw:: c_int;
3
4
4
5
use mio:: { self , Evented } ;
5
6
use once_cell:: sync:: Lazy ;
@@ -11,19 +12,22 @@ use crate::utils::abort_on_panic;
11
12
12
13
/// Data associated with a registered I/O handle.
13
14
#[ derive( Debug ) ]
14
- struct Entry {
15
+ pub struct Entry {
15
16
/// A unique identifier.
16
17
token : mio:: Token ,
17
18
19
+ /// File descriptor.
20
+ fd : Option < c_int > ,
21
+
18
22
/// Tasks that are blocked on reading from this I/O handle.
19
- readers : Mutex < Vec < Waker > > ,
23
+ pub readers : Mutex < Vec < Waker > > ,
20
24
21
25
/// Thasks that are blocked on writing to this I/O handle.
22
- writers : Mutex < Vec < Waker > > ,
26
+ pub writers : Mutex < Vec < Waker > > ,
23
27
}
24
28
25
29
/// The state of a networking driver.
26
- struct Reactor {
30
+ pub struct Reactor {
27
31
/// A mio instance that polls for new events.
28
32
poller : mio:: Poll ,
29
33
@@ -51,14 +55,14 @@ impl Reactor {
51
55
} ;
52
56
53
57
// Register a dummy I/O handle for waking up the polling thread.
54
- let entry = reactor. register ( & reactor. notify_reg . 0 ) ?;
58
+ let entry = reactor. register ( & reactor. notify_reg . 0 , None ) ?;
55
59
reactor. notify_token = entry. token ;
56
60
57
61
Ok ( reactor)
58
62
}
59
63
60
64
/// Registers an I/O event source and returns its associated entry.
61
- fn register ( & self , source : & dyn Evented ) -> io:: Result < Arc < Entry > > {
65
+ pub fn register ( & self , source : & dyn Evented , fd : Option < c_int > ) -> io:: Result < Arc < Entry > > {
62
66
let mut entries = self . entries . lock ( ) . unwrap ( ) ;
63
67
64
68
// Reserve a vacant spot in the slab and use its key as the token value.
@@ -68,6 +72,7 @@ impl Reactor {
68
72
// Allocate an entry and insert it into the slab.
69
73
let entry = Arc :: new ( Entry {
70
74
token,
75
+ fd,
71
76
readers : Mutex :: new ( Vec :: new ( ) ) ,
72
77
writers : Mutex :: new ( Vec :: new ( ) ) ,
73
78
} ) ;
@@ -82,7 +87,7 @@ impl Reactor {
82
87
}
83
88
84
89
/// Deregisters an I/O event source associated with an entry.
85
- fn deregister ( & self , source : & dyn Evented , entry : & Entry ) -> io:: Result < ( ) > {
90
+ pub fn deregister ( & self , source : & dyn Evented , entry : & Entry ) -> io:: Result < ( ) > {
86
91
// Deregister the I/O object from the mio instance.
87
92
self . poller . deregister ( source) ?;
88
93
@@ -92,6 +97,17 @@ impl Reactor {
92
97
Ok ( ( ) )
93
98
}
94
99
100
+ /// Deregisters an I/O event source associated with a file descriptor.
101
+ pub fn deregister_fd ( & self , source : & dyn Evented , fd : c_int ) -> io:: Result < ( ) > {
102
+ // Deregister the I/O object from the mio instance.
103
+ self . poller . deregister ( source) ?;
104
+
105
+ // Remove the entry associated with the I/O object.
106
+ self . entries . lock ( ) . unwrap ( ) . retain ( |_, e| e. fd != Some ( fd) ) ;
107
+
108
+ Ok ( ( ) )
109
+ }
110
+
95
111
// fn notify(&self) {
96
112
// self.notify_reg
97
113
// .1
@@ -101,7 +117,7 @@ impl Reactor {
101
117
}
102
118
103
119
/// The state of the global networking driver.
104
- static REACTOR : Lazy < Reactor > = Lazy :: new ( || {
120
+ pub static REACTOR : Lazy < Reactor > = Lazy :: new ( || {
105
121
// Spawn a thread that waits on the poller for new events and wakes up tasks blocked on I/O
106
122
// handles.
107
123
std:: thread:: Builder :: new ( )
@@ -181,7 +197,7 @@ impl<T: Evented> Watcher<T> {
181
197
pub fn new ( source : T ) -> Watcher < T > {
182
198
Watcher {
183
199
entry : REACTOR
184
- . register ( & source)
200
+ . register ( & source, None )
185
201
. expect ( "cannot register an I/O event source" ) ,
186
202
source : Some ( source) ,
187
203
}
0 commit comments