@@ -333,36 +333,76 @@ pub mod split {
333333 }
334334 }
335335
336- #[ cfg( feature="__splitref__" ) ]
337- const _: ( ) = {
338- #[ cfg( feature="rt_tokio" ) ]
339- impl < ' split > Splitable < ' split > for tokio:: net:: TcpStream {
340- type ReadHalf = tokio:: net:: tcp:: ReadHalf < ' split > ;
341- type WriteHalf = tokio:: net:: tcp:: WriteHalf < ' split > ;
342- fn split ( & ' split mut self ) -> ( Self :: ReadHalf , Self :: WriteHalf ) {
343- <tokio:: net:: TcpStream >:: split ( self )
344- }
345- }
346- #[ cfg( feature="rt_glommio" ) ]
336+ #[ cfg( any( feature="rt_smol" , feature="rt_glommio" ) ) ]
337+ const _: ( /* futures-io users */ ) = {
347338 impl < ' split , T : AsyncRead + AsyncWrite + Unpin + ' split > Splitable < ' split > for T {
348- type ReadHalf = futures_util:: io:: ReadHalf < & ' split mut T > ;
339+ type ReadHalf = futures_util:: io:: ReadHalf < & ' split mut T > ;
349340 type WriteHalf = futures_util:: io:: WriteHalf < & ' split mut T > ;
350341 fn split ( & ' split mut self ) -> ( Self :: ReadHalf , Self :: WriteHalf ) {
351342 AsyncRead :: split ( self )
352343 }
353344 }
354345 } ;
355- #[ cfg( feature="__clone__" ) ]
356- const _: ( ) = {
357- impl < ' split , C : AsyncRead + AsyncWrite + Unpin + Sized + Clone + ' split > Splitable < ' split > for C {
358- type ReadHalf = Self ;
359- type WriteHalf = & ' split mut Self ;
346+
347+ #[ cfg( any( feature="rt_tokio" ) ) ]
348+ const _: ( /* tokio::io users */ ) = {
349+ impl < ' split , T : AsyncRead + AsyncWrite + Unpin + ' split > Splitable < ' split > for T {
350+ type ReadHalf = TokioIoReadHalf < ' split , T > ;
351+ type WriteHalf = TokioIoWriteHalf < ' split , T > ;
360352 fn split ( & ' split mut self ) -> ( Self :: ReadHalf , Self :: WriteHalf ) {
361- ( self . clone ( ) , self )
353+ let ( r, w) = futures_util:: lock:: BiLock :: new ( self ) ;
354+ ( TokioIoReadHalf ( r) , TokioIoWriteHalf ( w) )
355+ }
356+ }
357+
358+ /*
359+ * based on https://github.com/rust-lang/futures-rs/blob/de9274e655b2fff8c9630a259a473b71a6b79dda/futures-util/src/io/split.rs
360+ */
361+ pub struct TokioIoReadHalf < ' split , T > ( futures_util:: lock:: BiLock < & ' split mut T > ) ;
362+ pub struct TokioIoWriteHalf < ' split , T > ( futures_util:: lock:: BiLock < & ' split mut T > ) ;
363+ fn lock_and_then < T , U , E > (
364+ lock : & futures_util:: lock:: BiLock < T > ,
365+ cx : & mut std:: task:: Context < ' _ > ,
366+ f : impl FnOnce ( std:: pin:: Pin < & mut T > , & mut std:: task:: Context < ' _ > ) -> std:: task:: Poll < Result < U , E > >
367+ ) -> std:: task:: Poll < Result < U , E > > {
368+ let mut l = futures_util:: ready!( lock. poll_lock( cx) ) ;
369+ f ( l. as_pin_mut ( ) , cx)
370+ }
371+ impl < ' split , T : tokio:: io:: AsyncRead + Unpin > tokio:: io:: AsyncRead for TokioIoReadHalf < ' split , T > {
372+ #[ inline]
373+ fn poll_read (
374+ self : std:: pin:: Pin < & mut Self > ,
375+ cx : & mut std:: task:: Context < ' _ > ,
376+ buf : & mut tokio:: io:: ReadBuf < ' _ >
377+ ) -> std:: task:: Poll < std:: io:: Result < ( ) > > {
378+ lock_and_then ( & self . 0 , cx, |l, cx| l. poll_read ( cx, buf) )
379+ }
380+ }
381+ impl < ' split , T : tokio:: io:: AsyncWrite + Unpin > tokio:: io:: AsyncWrite for TokioIoWriteHalf < ' split , T > {
382+ #[ inline]
383+ fn poll_write (
384+ self : std:: pin:: Pin < & mut Self > ,
385+ cx : & mut std:: task:: Context < ' _ > ,
386+ buf : & [ u8 ]
387+ ) -> std:: task:: Poll < std:: io:: Result < usize > > {
388+ lock_and_then ( & self . 0 , cx, |l, cx| l. poll_write ( cx, buf) )
389+ }
390+ #[ inline]
391+ fn poll_flush (
392+ self : std:: pin:: Pin < & mut Self > ,
393+ cx : & mut std:: task:: Context < ' _ >
394+ ) -> std:: task:: Poll < std:: io:: Result < ( ) > > {
395+ lock_and_then ( & self . 0 , cx, |l, cx| l. poll_flush ( cx) )
396+ }
397+ fn poll_shutdown (
398+ self : std:: pin:: Pin < & mut Self > ,
399+ cx : & mut std:: task:: Context < ' _ >
400+ ) -> std:: task:: Poll < std:: io:: Result < ( ) > > {
401+ lock_and_then ( & self . 0 , cx, |l, cx| l. poll_shutdown ( cx) )
362402 }
363403 }
364404 } ;
365-
405+
366406 pub struct ReadHalf < C : AsyncRead + Unpin > {
367407 __closed__ : Arc < RwLock < bool > > ,
368408 conn : C ,
@@ -433,3 +473,15 @@ pub mod split {
433473 }
434474 }
435475}
476+
477+ #[ cfg( test) ]
478+ mod tests {
479+ use super :: * ;
480+
481+ #[ cfg( feature="__runtime__" ) ]
482+ #[ test]
483+ fn test_impl_splitable ( ) {
484+ fn assert_impl_splitable < T : split:: Splitable < ' static > > ( ) { }
485+ assert_impl_splitable :: < crate :: runtime:: net:: TcpStream > ( ) ;
486+ }
487+ }
0 commit comments