@@ -183,7 +183,7 @@ pub struct IoHandle<T: Evented> {
183183 entry : Arc < Entry > ,
184184
185185 /// The I/O event source.
186- source : T ,
186+ source : Option < T > ,
187187}
188188
189189impl < T : Evented > IoHandle < T > {
@@ -196,13 +196,13 @@ impl<T: Evented> IoHandle<T> {
196196 entry : REACTOR
197197 . register ( & source)
198198 . expect ( "cannot register an I/O event source" ) ,
199- source,
199+ source : Some ( source ) ,
200200 }
201201 }
202202
203203 /// Returns a reference to the inner I/O event source.
204204 pub fn get_ref ( & self ) -> & T {
205- & self . source
205+ self . source . as_ref ( ) . unwrap ( )
206206 }
207207
208208 /// Polls the I/O handle for reading.
@@ -286,13 +286,26 @@ impl<T: Evented> IoHandle<T> {
286286
287287 Ok ( ( ) )
288288 }
289+
290+ /// Deregisters and returns the inner I/O source.
291+ ///
292+ /// This method is typically used to convert `IoHandle`s to raw file descriptors/handles.
293+ pub fn into_inner ( mut self ) -> T {
294+ let source = self . source . take ( ) . unwrap ( ) ;
295+ REACTOR
296+ . deregister ( & source, & self . entry )
297+ . expect ( "cannot deregister I/O event source" ) ;
298+ source
299+ }
289300}
290301
291302impl < T : Evented > Drop for IoHandle < T > {
292303 fn drop ( & mut self ) {
293- REACTOR
294- . deregister ( & self . source , & self . entry )
295- . expect ( "cannot deregister I/O event source" ) ;
304+ if let Some ( ref source) = self . source {
305+ REACTOR
306+ . deregister ( source, & self . entry )
307+ . expect ( "cannot deregister I/O event source" ) ;
308+ }
296309 }
297310}
298311
@@ -313,7 +326,7 @@ impl<T: Evented + std::io::Read + Unpin> AsyncRead for IoHandle<T> {
313326 ) -> Poll < io:: Result < usize > > {
314327 futures_core:: ready!( Pin :: new( & mut * self ) . poll_readable( cx) ?) ;
315328
316- match self . source . read ( buf) {
329+ match self . source . as_mut ( ) . unwrap ( ) . read ( buf) {
317330 Err ( ref err) if err. kind ( ) == io:: ErrorKind :: WouldBlock => {
318331 self . clear_readable ( cx) ?;
319332 Poll :: Pending
@@ -334,7 +347,7 @@ where
334347 ) -> Poll < io:: Result < usize > > {
335348 futures_core:: ready!( Pin :: new( & mut * self ) . poll_readable( cx) ?) ;
336349
337- match ( & self . source ) . read ( buf) {
350+ match self . source . as_ref ( ) . unwrap ( ) . read ( buf) {
338351 Err ( ref err) if err. kind ( ) == io:: ErrorKind :: WouldBlock => {
339352 self . clear_readable ( cx) ?;
340353 Poll :: Pending
@@ -352,7 +365,7 @@ impl<T: Evented + std::io::Write + Unpin> AsyncWrite for IoHandle<T> {
352365 ) -> Poll < io:: Result < usize > > {
353366 futures_core:: ready!( self . poll_writable( cx) ?) ;
354367
355- match self . source . write ( buf) {
368+ match self . source . as_mut ( ) . unwrap ( ) . write ( buf) {
356369 Err ( ref err) if err. kind ( ) == io:: ErrorKind :: WouldBlock => {
357370 self . clear_writable ( cx) ?;
358371 Poll :: Pending
@@ -364,7 +377,7 @@ impl<T: Evented + std::io::Write + Unpin> AsyncWrite for IoHandle<T> {
364377 fn poll_flush ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < io:: Result < ( ) > > {
365378 futures_core:: ready!( self . poll_writable( cx) ?) ;
366379
367- match self . source . flush ( ) {
380+ match self . source . as_mut ( ) . unwrap ( ) . flush ( ) {
368381 Err ( ref err) if err. kind ( ) == io:: ErrorKind :: WouldBlock => {
369382 self . clear_writable ( cx) ?;
370383 Poll :: Pending
@@ -389,7 +402,7 @@ where
389402 ) -> Poll < io:: Result < usize > > {
390403 futures_core:: ready!( self . poll_writable( cx) ?) ;
391404
392- match ( & self . source ) . write ( buf) {
405+ match self . get_ref ( ) . write ( buf) {
393406 Err ( ref err) if err. kind ( ) == io:: ErrorKind :: WouldBlock => {
394407 self . clear_writable ( cx) ?;
395408 Poll :: Pending
@@ -401,7 +414,7 @@ where
401414 fn poll_flush ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < io:: Result < ( ) > > {
402415 futures_core:: ready!( self . poll_writable( cx) ?) ;
403416
404- match ( & self . source ) . flush ( ) {
417+ match self . get_ref ( ) . flush ( ) {
405418 Err ( ref err) if err. kind ( ) == io:: ErrorKind :: WouldBlock => {
406419 self . clear_writable ( cx) ?;
407420 Poll :: Pending
0 commit comments