1- use crate :: net:: { IpProtocol :: Tcp , * } ;
1+ use crate :: net:: { tcp :: split , IpProtocol :: Tcp , * } ;
22use bytes:: { Buf , BufMut , BytesMut } ;
3+ use spin:: Mutex ;
34#[ cfg( unix) ]
45use std:: os:: unix:: io:: { AsRawFd , RawFd } ;
56use std:: {
@@ -17,10 +18,10 @@ pub struct TcpStream {
1718 pub ( super ) addr : SocketAddr ,
1819 pub ( super ) peer : SocketAddr ,
1920 /// Buffer write data to be flushed.
20- pub ( super ) write_buf : BytesMut ,
21- pub ( super ) read_buf : Bytes ,
21+ pub ( super ) write_buf : Mutex < BytesMut > ,
22+ pub ( super ) read_buf : Mutex < Bytes > ,
2223 pub ( super ) tx : PayloadSender ,
23- pub ( super ) rx : PayloadReceiver ,
24+ pub ( super ) rx : Mutex < PayloadReceiver > ,
2425}
2526
2627impl fmt:: Debug for TcpStream {
@@ -80,7 +81,7 @@ impl TcpStream {
8081 write_buf : Default :: default ( ) ,
8182 read_buf : Default :: default ( ) ,
8283 tx,
83- rx,
84+ rx : Mutex :: new ( rx ) ,
8485 } ;
8586 Ok ( stream)
8687 }
@@ -108,83 +109,114 @@ impl TcpStream {
108109 /// to arrive. On success, returns the number of bytes read. Because
109110 /// `try_read_buf()` is non-blocking, the buffer does not have to be stored
110111 /// by the async task and can exist entirely on the stack.
111- pub fn try_read_buf < B : BufMut > ( & mut self , buf : & mut B ) -> io:: Result < usize > {
112+ pub fn try_read_buf < B : BufMut > ( & self , buf : & mut B ) -> io:: Result < usize > {
112113 // read the buffer if not empty
113- if !self . read_buf . is_empty ( ) {
114- let len = self . read_buf . len ( ) . min ( buf. remaining_mut ( ) ) ;
115- buf. put_slice ( & self . read_buf [ ..len] ) ;
116- self . read_buf . advance ( len) ;
114+ let mut read_buf = self . read_buf . lock ( ) ;
115+ if !read_buf. is_empty ( ) {
116+ let len = read_buf. len ( ) . min ( buf. remaining_mut ( ) ) ;
117+ buf. put_slice ( & read_buf[ ..len] ) ;
118+ read_buf. advance ( len) ;
117119 return Ok ( len) ;
118120 }
119121 Err ( io:: Error :: new (
120122 io:: ErrorKind :: WouldBlock ,
121123 "read buffer is empty" ,
122124 ) )
123125 }
124- }
125126
126- # [ cfg ( unix ) ]
127- impl AsRawFd for TcpStream {
128- fn as_raw_fd ( & self ) -> RawFd {
129- todo ! ( "TcpStream::as_raw_fd" ) ;
127+ /// Splits a `TcpStream` into a read half and a write half, which can be used
128+ /// to read and write the stream concurrently.
129+ pub fn split ( & mut self ) -> ( split :: ReadHalf < ' _ > , split :: WriteHalf < ' _ > ) {
130+ split :: split ( self )
130131 }
131- }
132132
133- impl AsyncRead for TcpStream {
134- fn poll_read (
135- mut self : Pin < & mut Self > ,
133+ /// Splits a `TcpStream` into a read half and a write half, which can be
134+ /// used to read and write the stream concurrently.
135+ pub fn into_split ( self ) -> ( split:: OwnedReadHalf , split:: OwnedWriteHalf ) {
136+ split:: split_owned ( self )
137+ }
138+
139+ /// `poll_read` that takes `&self`.
140+ pub ( super ) fn poll_read_priv (
141+ & self ,
136142 cx : & mut Context < ' _ > ,
137143 buf : & mut ReadBuf < ' _ > ,
138144 ) -> Poll < Result < ( ) > > {
139145 // read the buffer if not empty
140- if !self . read_buf . is_empty ( ) {
141- let len = self . read_buf . len ( ) . min ( buf. remaining ( ) ) ;
142- buf. put_slice ( & self . read_buf [ ..len] ) ;
143- self . read_buf . advance ( len) ;
146+ if self . try_read_buf ( buf) . is_ok ( ) {
144147 return Poll :: Ready ( Ok ( ( ) ) ) ;
145148 }
149+
146150 // otherwise wait on channel
147- let poll_res = { self . rx . poll_next_unpin ( cx) } ;
151+ let poll_res = { self . rx . lock ( ) . poll_next_unpin ( cx) } ;
148152 match poll_res {
149153 Poll :: Pending => Poll :: Pending ,
150154 Poll :: Ready ( Some ( data) ) => {
151- self . read_buf = * data. downcast :: < Bytes > ( ) . unwrap ( ) ;
152- self . poll_read ( cx, buf)
155+ * self . read_buf . lock ( ) = * data. downcast :: < Bytes > ( ) . unwrap ( ) ;
156+ self . poll_read_priv ( cx, buf)
153157 }
154158 // ref: https://man7.org/linux/man-pages/man2/recv.2.html
155159 // > When a stream socket peer has performed an orderly shutdown, the
156160 // > return value will be 0 (the traditional "end-of-file" return).
157161 Poll :: Ready ( None ) => Poll :: Ready ( Ok ( ( ) ) ) ,
158162 }
159163 }
160- }
161164
162- impl AsyncWrite for TcpStream {
163- fn poll_write (
164- mut self : Pin < & mut Self > ,
165- _cx : & mut Context < ' _ > ,
166- buf : & [ u8 ] ,
167- ) -> Poll < Result < usize > > {
168- self . write_buf . extend_from_slice ( buf) ;
165+ /// `poll_write` that takes `&self`.
166+ pub ( super ) fn poll_write_priv ( & self , _cx : & mut Context < ' _ > , buf : & [ u8 ] ) -> Poll < Result < usize > > {
167+ self . write_buf . lock ( ) . extend_from_slice ( buf) ;
169168 // TODO: simulate buffer full, partial write
170169 Poll :: Ready ( Ok ( buf. len ( ) ) )
171170 }
172171
173- fn poll_flush ( mut self : Pin < & mut Self > , _cx : & mut Context < ' _ > ) -> Poll < Result < ( ) > > {
172+ /// `poll_flush` that takes `&self`.
173+ pub ( super ) fn poll_flush_priv ( & self , _cx : & mut Context < ' _ > ) -> Poll < Result < ( ) > > {
174174 // send data
175- let data = self . write_buf . split ( ) . freeze ( ) ;
175+ let data = self . write_buf . lock ( ) . split ( ) . freeze ( ) ;
176176 self . tx
177177 . send ( Box :: new ( data) )
178178 . ok_or_else ( || io:: Error :: new ( io:: ErrorKind :: ConnectionReset , "connection reset" ) ) ?;
179179 Poll :: Ready ( Ok ( ( ) ) )
180180 }
181181
182- fn poll_shutdown ( self : Pin < & mut Self > , _: & mut Context < ' _ > ) -> Poll < Result < ( ) > > {
182+ /// `poll_shutdown` that takes `&self`.
183+ pub ( super ) fn poll_shutdown_priv ( & self , _: & mut Context < ' _ > ) -> Poll < Result < ( ) > > {
183184 // TODO: simulate shutdown
184185 Poll :: Ready ( Ok ( ( ) ) )
185186 }
186187}
187188
189+ #[ cfg( unix) ]
190+ impl AsRawFd for TcpStream {
191+ fn as_raw_fd ( & self ) -> RawFd {
192+ todo ! ( "TcpStream::as_raw_fd" ) ;
193+ }
194+ }
195+
196+ impl AsyncRead for TcpStream {
197+ fn poll_read (
198+ self : Pin < & mut Self > ,
199+ cx : & mut Context < ' _ > ,
200+ buf : & mut ReadBuf < ' _ > ,
201+ ) -> Poll < Result < ( ) > > {
202+ self . poll_read_priv ( cx, buf)
203+ }
204+ }
205+
206+ impl AsyncWrite for TcpStream {
207+ fn poll_write ( self : Pin < & mut Self > , cx : & mut Context < ' _ > , buf : & [ u8 ] ) -> Poll < Result < usize > > {
208+ self . poll_write_priv ( cx, buf)
209+ }
210+
211+ fn poll_flush ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) > > {
212+ self . poll_flush_priv ( cx)
213+ }
214+
215+ fn poll_shutdown ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) > > {
216+ self . poll_shutdown_priv ( cx)
217+ }
218+ }
219+
188220/// Socket registered in the [`Network`].
189221struct TcpStreamSocket ;
190222
0 commit comments