1
1
use std:: io:: { IoSlice , IoSliceMut , Read as _, Write as _} ;
2
2
use std:: net:: SocketAddr ;
3
3
use std:: pin:: Pin ;
4
+ use std:: sync:: Arc ;
4
5
5
6
use crate :: future;
6
7
use crate :: io:: { self , Read , Write } ;
@@ -44,9 +45,9 @@ use crate::task::{Context, Poll};
44
45
/// #
45
46
/// # Ok(()) }) }
46
47
/// ```
47
- #[ derive( Debug ) ]
48
+ #[ derive( Debug , Clone ) ]
48
49
pub struct TcpStream {
49
- pub ( super ) watcher : Watcher < mio:: net:: TcpStream > ,
50
+ pub ( super ) watcher : Arc < Watcher < mio:: net:: TcpStream > > ,
50
51
}
51
52
52
53
impl TcpStream {
@@ -71,9 +72,7 @@ impl TcpStream {
71
72
/// ```
72
73
pub async fn connect < A : ToSocketAddrs > ( addrs : A ) -> io:: Result < TcpStream > {
73
74
let mut last_err = None ;
74
- let addrs = addrs
75
- . to_socket_addrs ( )
76
- . await ?;
75
+ let addrs = addrs. to_socket_addrs ( ) . await ?;
77
76
78
77
for addr in addrs {
79
78
// mio's TcpStream::connect is non-blocking and may just be in progress
@@ -84,16 +83,20 @@ impl TcpStream {
84
83
Ok ( s) => Watcher :: new ( s) ,
85
84
Err ( e) => {
86
85
last_err = Some ( e) ;
87
- continue
86
+ continue ;
88
87
}
89
88
} ;
90
89
91
90
future:: poll_fn ( |cx| watcher. poll_write_ready ( cx) ) . await ;
92
91
93
92
match watcher. get_ref ( ) . take_error ( ) {
94
- Ok ( None ) => return Ok ( TcpStream { watcher } ) ,
93
+ Ok ( None ) => {
94
+ return Ok ( TcpStream {
95
+ watcher : Arc :: new ( watcher) ,
96
+ } ) ;
97
+ }
95
98
Ok ( Some ( e) ) => last_err = Some ( e) ,
96
- Err ( e) => last_err = Some ( e)
99
+ Err ( e) => last_err = Some ( e) ,
97
100
}
98
101
}
99
102
@@ -369,7 +372,7 @@ impl From<std::net::TcpStream> for TcpStream {
369
372
fn from ( stream : std:: net:: TcpStream ) -> TcpStream {
370
373
let mio_stream = mio:: net:: TcpStream :: from_stream ( stream) . unwrap ( ) ;
371
374
TcpStream {
372
- watcher : Watcher :: new ( mio_stream) ,
375
+ watcher : Arc :: new ( Watcher :: new ( mio_stream) ) ,
373
376
}
374
377
}
375
378
}
@@ -391,7 +394,10 @@ cfg_unix! {
391
394
392
395
impl IntoRawFd for TcpStream {
393
396
fn into_raw_fd( self ) -> RawFd {
394
- self . watcher. into_inner( ) . into_raw_fd( )
397
+ // TODO(stjepang): This does not mean `RawFd` is now the sole owner of the file
398
+ // descriptor because it's possible that there are other clones of this `TcpStream`
399
+ // using it at the same time. We should probably document that behavior.
400
+ self . as_raw_fd( )
395
401
}
396
402
}
397
403
}
0 commit comments