@@ -37,7 +37,7 @@ pub struct Loop {
37
37
id : usize ,
38
38
io : mio:: Poll ,
39
39
events : mio:: Events ,
40
- tx : Arc < Sender < Message > > ,
40
+ inner : Arc < LoopHandleInner > ,
41
41
rx : Receiver < Message > ,
42
42
io_dispatch : RefCell < Slab < ScheduledIo , usize > > ,
43
43
task_dispatch : RefCell < Slab < ScheduledTask , usize > > ,
@@ -62,6 +62,31 @@ pub struct Loop {
62
62
timeouts : RefCell < Slab < ( Timeout , TimeoutState ) , usize > > ,
63
63
}
64
64
65
+ impl Drop for Loop {
66
+ fn drop ( & mut self ) {
67
+ // mark event loop as dead, so all schedule operations will be rejected
68
+ self . inner . alive . store ( 0 , Ordering :: SeqCst ) ;
69
+
70
+ // Unpark all tasks.
71
+ // It has no effect for tasks in this event loop,
72
+ // however tasks in another executors get an error
73
+ // when they do `poll` right after wakeup.
74
+ for io in self . io_dispatch . borrow_mut ( ) . iter_mut ( ) {
75
+ if let Some ( ref mut reader) = io. reader {
76
+ reader. unpark ( ) ;
77
+ }
78
+ if let Some ( ref mut writer) = io. writer {
79
+ writer. unpark ( ) ;
80
+ }
81
+ }
82
+ }
83
+ }
84
+
85
+ struct LoopHandleInner {
86
+ tx : Arc < Sender < Message > > ,
87
+ alive : AtomicUsize , // 1 iff even loop is alive
88
+ }
89
+
65
90
/// Handle to an event loop, used to construct I/O objects, send messages, and
66
91
/// otherwise interact indirectly with the event loop itself.
67
92
///
@@ -70,7 +95,7 @@ pub struct Loop {
70
95
#[ derive( Clone ) ]
71
96
pub struct LoopHandle {
72
97
id : usize ,
73
- tx : Arc < Sender < Message > > ,
98
+ inner : Arc < LoopHandleInner > ,
74
99
}
75
100
76
101
/// A non-sendable handle to an event loop, useful for manufacturing instances
@@ -145,7 +170,10 @@ impl Loop {
145
170
id : NEXT_LOOP_ID . fetch_add ( 1 , Ordering :: Relaxed ) ,
146
171
io : io,
147
172
events : mio:: Events :: with_capacity ( 1024 ) ,
148
- tx : Arc :: new ( tx) ,
173
+ inner : Arc :: new ( LoopHandleInner {
174
+ tx : Arc :: new ( tx) ,
175
+ alive : AtomicUsize :: new ( 1 ) ,
176
+ } ) ,
149
177
rx : rx,
150
178
io_dispatch : RefCell :: new ( Slab :: with_capacity ( SLAB_CAPACITY ) ) ,
151
179
task_dispatch : RefCell :: new ( Slab :: with_capacity ( SLAB_CAPACITY ) ) ,
@@ -169,7 +197,7 @@ impl Loop {
169
197
pub fn handle ( & self ) -> LoopHandle {
170
198
LoopHandle {
171
199
id : self . id ,
172
- tx : self . tx . clone ( ) ,
200
+ inner : self . inner . clone ( ) ,
173
201
}
174
202
}
175
203
@@ -516,7 +544,7 @@ impl LoopHandle {
516
544
lp. notify ( msg) ;
517
545
}
518
546
None => {
519
- match self . tx . send ( msg) {
547
+ match self . inner . tx . send ( msg) {
520
548
Ok ( ( ) ) => { }
521
549
522
550
// This should only happen when there was an error
0 commit comments