1
1
use crate :: { Interest , Token } ;
2
2
use std:: mem:: { self , MaybeUninit } ;
3
3
use std:: ops:: { Deref , DerefMut } ;
4
- use std:: os:: fd:: { AsRawFd , RawFd } ;
4
+ use std:: os:: fd:: { AsRawFd , FromRawFd , OwnedFd , RawFd } ;
5
5
#[ cfg( debug_assertions) ]
6
6
use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
7
7
use std:: time:: Duration ;
@@ -65,24 +65,23 @@ macro_rules! kevent {
65
65
pub struct Selector {
66
66
#[ cfg( debug_assertions) ]
67
67
id : usize ,
68
- kq : RawFd ,
68
+ kq : OwnedFd ,
69
69
}
70
70
71
71
impl Selector {
72
72
pub fn new ( ) -> io:: Result < Selector > {
73
- let kq = syscall ! ( kqueue( ) ) ?;
74
- let selector = Selector {
73
+ // SAFETY: `kqueue(2)` ensures the fd is valid.
74
+ let kq = unsafe { OwnedFd :: from_raw_fd ( syscall ! ( kqueue( ) ) ?) } ;
75
+ syscall ! ( fcntl( kq. as_raw_fd( ) , libc:: F_SETFD , libc:: FD_CLOEXEC ) ) ?;
76
+ Ok ( Selector {
75
77
#[ cfg( debug_assertions) ]
76
78
id : NEXT_ID . fetch_add ( 1 , Ordering :: Relaxed ) ,
77
79
kq,
78
- } ;
79
-
80
- syscall ! ( fcntl( kq, libc:: F_SETFD , libc:: FD_CLOEXEC ) ) ?;
81
- Ok ( selector)
80
+ } )
82
81
}
83
82
84
83
pub fn try_clone ( & self ) -> io:: Result < Selector > {
85
- syscall ! ( fcntl ( self . kq, libc :: F_DUPFD_CLOEXEC , super :: LOWEST_FD ) ) . map ( |kq| Selector {
84
+ self . kq . try_clone ( ) . map ( |kq| Selector {
86
85
// It's the same selector, so we use the same id.
87
86
#[ cfg( debug_assertions) ]
88
87
id : self . id ,
@@ -106,7 +105,7 @@ impl Selector {
106
105
107
106
events. clear ( ) ;
108
107
syscall ! ( kevent(
109
- self . kq,
108
+ self . kq. as_raw_fd ( ) ,
110
109
ptr:: null( ) ,
111
110
0 ,
112
111
events. as_mut_ptr( ) ,
@@ -156,7 +155,7 @@ impl Selector {
156
155
// the array.
157
156
slice:: from_raw_parts_mut ( changes[ 0 ] . as_mut_ptr ( ) , n_changes)
158
157
} ;
159
- kevent_register ( self . kq , changes, & [ libc:: EPIPE as i64 ] )
158
+ kevent_register ( self . kq . as_raw_fd ( ) , changes, & [ libc:: EPIPE as i64 ] )
160
159
}
161
160
162
161
pub fn reregister ( & self , fd : RawFd , token : Token , interests : Interest ) -> io:: Result < ( ) > {
@@ -186,7 +185,7 @@ impl Selector {
186
185
//
187
186
// For the explanation of ignoring `EPIPE` see `register`.
188
187
kevent_register (
189
- self . kq ,
188
+ self . kq . as_raw_fd ( ) ,
190
189
& mut changes,
191
190
& [ libc:: ENOENT as i64 , libc:: EPIPE as i64 ] ,
192
191
)
@@ -204,7 +203,7 @@ impl Selector {
204
203
// the ENOENT error when it comes up. The ENOENT error informs us that
205
204
// the filter wasn't there in first place, but we don't really care
206
205
// about that since our goal is to remove it.
207
- kevent_register ( self . kq , & mut changes, & [ libc:: ENOENT as i64 ] )
206
+ kevent_register ( self . kq . as_raw_fd ( ) , & mut changes, & [ libc:: ENOENT as i64 ] )
208
207
}
209
208
210
209
// Used by `Waker`.
@@ -224,7 +223,8 @@ impl Selector {
224
223
token. 0
225
224
) ;
226
225
227
- syscall ! ( kevent( self . kq, & kevent, 1 , & mut kevent, 1 , ptr:: null( ) ) ) . and_then ( |_| {
226
+ let kq = self . kq . as_raw_fd ( ) ;
227
+ syscall ! ( kevent( kq, & kevent, 1 , & mut kevent, 1 , ptr:: null( ) ) ) . and_then ( |_| {
228
228
if ( kevent. flags & libc:: EV_ERROR ) != 0 && kevent. data != 0 {
229
229
Err ( io:: Error :: from_raw_os_error ( kevent. data as i32 ) )
230
230
} else {
@@ -250,7 +250,8 @@ impl Selector {
250
250
) ;
251
251
kevent. fflags = libc:: NOTE_TRIGGER ;
252
252
253
- syscall ! ( kevent( self . kq, & kevent, 1 , & mut kevent, 1 , ptr:: null( ) ) ) . and_then ( |_| {
253
+ let kq = self . kq . as_raw_fd ( ) ;
254
+ syscall ! ( kevent( kq, & kevent, 1 , & mut kevent, 1 , ptr:: null( ) ) ) . and_then ( |_| {
254
255
if ( kevent. flags & libc:: EV_ERROR ) != 0 && kevent. data != 0 {
255
256
Err ( io:: Error :: from_raw_os_error ( kevent. data as i32 ) )
256
257
} else {
@@ -314,15 +315,7 @@ cfg_io_source! {
314
315
315
316
impl AsRawFd for Selector {
316
317
fn as_raw_fd ( & self ) -> RawFd {
317
- self . kq
318
- }
319
- }
320
-
321
- impl Drop for Selector {
322
- fn drop ( & mut self ) {
323
- if let Err ( err) = syscall ! ( close( self . kq) ) {
324
- error ! ( "error closing kqueue: {}" , err) ;
325
- }
318
+ self . kq . as_raw_fd ( )
326
319
}
327
320
}
328
321
0 commit comments