File tree Expand file tree Collapse file tree 2 files changed +21
-4
lines changed Expand file tree Collapse file tree 2 files changed +21
-4
lines changed Original file line number Diff line number Diff line change @@ -220,8 +220,17 @@ impl Handle {
220
220
let scheduled_io = self . registrations . allocate ( & mut self . synced . lock ( ) ) ?;
221
221
let token = scheduled_io. token ( ) ;
222
222
223
- // TODO: if this returns an err, the `ScheduledIo` leaks...
224
- self . registry . register ( source, token, interest. to_mio ( ) ) ?;
223
+ // we should remove the `scheduled_io` from the `registrations` set if registering
224
+ // the `source` with the OS fails. Otherwise it will leak the `scheduled_io`.
225
+ if let Err ( e) = self . registry . register ( source, token, interest. to_mio ( ) ) {
226
+ // safety: `scheduled_io` is part of the `registrations` set.
227
+ unsafe {
228
+ self . registrations
229
+ . remove ( & mut self . synced . lock ( ) , & scheduled_io)
230
+ } ;
231
+
232
+ return Err ( e) ;
233
+ }
225
234
226
235
// TODO: move this logic to `RegistrationSet` and use a `CountedLinkedList`
227
236
self . metrics . incr_fd_count ( ) ;
Original file line number Diff line number Diff line change @@ -102,13 +102,21 @@ impl RegistrationSet {
102
102
}
103
103
104
104
pub ( super ) fn release ( & self , synced : & mut Synced ) {
105
- for io in synced. pending_release . drain ( ..) {
105
+ let pending = std:: mem:: take ( & mut synced. pending_release ) ;
106
+
107
+ for io in pending {
106
108
// safety: the registration is part of our list
107
- let _ = unsafe { synced . registrations . remove ( io. as_ref ( ) . into ( ) ) } ;
109
+ unsafe { self . remove ( synced , io. as_ref ( ) ) }
108
110
}
109
111
110
112
self . num_pending_release . store ( 0 , Release ) ;
111
113
}
114
+
115
+ // This function is marked as unsafe, because the caller must make sure that
116
+ // `io` is part of the registration set.
117
+ pub ( super ) unsafe fn remove ( & self , synced : & mut Synced , io : & ScheduledIo ) {
118
+ let _ = synced. registrations . remove ( io. into ( ) ) ;
119
+ }
112
120
}
113
121
114
122
// Safety: `Arc` pins the inner data
You can’t perform that action at this time.
0 commit comments