@@ -12,14 +12,13 @@ use mio::event::Evented;
12
12
use std:: fmt;
13
13
use std:: io;
14
14
use std:: sync:: { Arc , Weak } ;
15
- use std:: task:: Waker ;
16
15
use std:: time:: Duration ;
17
16
18
17
/// I/O driver, backed by Mio
19
18
pub ( crate ) struct Driver {
20
19
/// Tracks the number of times `turn` is called. It is safe for this to wrap
21
20
/// as it is mostly used to determine when to call `compact()`
22
- tick : u16 ,
21
+ tick : u8 ,
23
22
24
23
/// Reuse the `mio::Events` value across calls to poll.
25
24
events : Option < mio:: Events > ,
@@ -40,6 +39,11 @@ pub(crate) struct Handle {
40
39
inner : Weak < Inner > ,
41
40
}
42
41
42
+ pub ( crate ) struct ReadyEvent {
43
+ tick : u8 ,
44
+ readiness : mio:: Ready ,
45
+ }
46
+
43
47
pub ( super ) struct Inner {
44
48
/// The underlying system event queue.
45
49
io : mio:: Poll ,
@@ -57,6 +61,11 @@ pub(super) enum Direction {
57
61
Write ,
58
62
}
59
63
64
+ enum Tick {
65
+ Set ( u8 ) ,
66
+ Clear ( u8 ) ,
67
+ }
68
+
60
69
// TODO: Don't use a fake token. Instead, reserve a slot entry for the wakeup
61
70
// token.
62
71
const TOKEN_WAKEUP : mio:: Token = mio:: Token ( 1 << 31 ) ;
@@ -122,11 +131,11 @@ impl Driver {
122
131
123
132
fn turn ( & mut self , max_wait : Option < Duration > ) -> io:: Result < ( ) > {
124
133
// How often to call `compact()` on the resource slab
125
- const COMPACT_INTERVAL : u16 = 256 ;
134
+ const COMPACT_INTERVAL : u8 = 255 ;
126
135
127
136
self . tick = self . tick . wrapping_add ( 1 ) ;
128
137
129
- if self . tick % COMPACT_INTERVAL == 0 {
138
+ if self . tick == COMPACT_INTERVAL {
130
139
self . resources . compact ( ) ;
131
140
}
132
141
@@ -160,39 +169,22 @@ impl Driver {
160
169
}
161
170
162
171
fn dispatch ( & mut self , token : mio:: Token , ready : mio:: Ready ) {
163
- let mut rd = None ;
164
- let mut wr = None ;
165
-
166
172
let addr = slab:: Address :: from_usize ( ADDRESS . unpack ( token. 0 ) ) ;
167
173
168
174
let io = match self . resources . get ( addr) {
169
175
Some ( io) => io,
170
176
None => return ,
171
177
} ;
172
178
173
- if io
174
- . set_readiness ( Some ( token . 0 ) , | curr| curr | ready. as_usize ( ) )
175
- . is_err ( )
176
- {
179
+ let set = io . set_readiness ( Some ( token . 0 ) , Tick :: Set ( self . tick ) , |curr| {
180
+ curr | ready. as_usize ( )
181
+ } ) ;
182
+ if set . is_err ( ) {
177
183
// token no longer valid!
178
184
return ;
179
185
}
180
186
181
- if ready. is_writable ( ) || platform:: is_hup ( ready) || platform:: is_error ( ready) {
182
- wr = io. writer . take_waker ( ) ;
183
- }
184
-
185
- if !( ready & ( !mio:: Ready :: writable ( ) ) ) . is_empty ( ) {
186
- rd = io. reader . take_waker ( ) ;
187
- }
188
-
189
- if let Some ( w) = rd {
190
- w. wake ( ) ;
191
- }
192
-
193
- if let Some ( w) = wr {
194
- w. wake ( ) ;
195
- }
187
+ io. wake ( ready) ;
196
188
}
197
189
}
198
190
@@ -202,8 +194,7 @@ impl Drop for Driver {
202
194
// If a task is waiting on the I/O resource, notify it. The task
203
195
// will then attempt to use the I/O resource and fail due to the
204
196
// driver being shutdown.
205
- io. reader . wake ( ) ;
206
- io. writer . wake ( ) ;
197
+ io. wake ( mio:: Ready :: all ( ) ) ;
207
198
} )
208
199
}
209
200
}
@@ -310,16 +301,6 @@ impl Inner {
310
301
pub ( super ) fn deregister_source ( & self , source : & dyn Evented ) -> io:: Result < ( ) > {
311
302
self . io . deregister ( source)
312
303
}
313
-
314
- /// Registers interest in the I/O resource associated with `token`.
315
- pub ( super ) fn register ( & self , io : & slab:: Ref < ScheduledIo > , dir : Direction , w : Waker ) {
316
- let waker = match dir {
317
- Direction :: Read => & io. reader ,
318
- Direction :: Write => & io. writer ,
319
- } ;
320
-
321
- waker. register ( w) ;
322
- }
323
304
}
324
305
325
306
impl Direction {
0 commit comments