@@ -6,6 +6,7 @@ use crate::net::SocketAddrV4;
66use crate :: ptr:: NonNull ;
77use crate :: sync:: atomic:: { AtomicBool , Ordering } ;
88use crate :: sys:: pal:: helpers;
9+ use crate :: time:: { Duration , Instant } ;
910
1011const TYPE_OF_SERVICE : u8 = 8 ;
1112const TIME_TO_LIVE : u8 = 255 ;
@@ -66,7 +67,7 @@ impl Tcp4 {
6667 if r. is_error ( ) { Err ( crate :: io:: Error :: from_raw_os_error ( r. as_usize ( ) ) ) } else { Ok ( ( ) ) }
6768 }
6869
69- pub ( crate ) fn connect ( & self ) -> io:: Result < ( ) > {
70+ pub ( crate ) fn connect ( & self , timeout : Option < Duration > ) -> io:: Result < ( ) > {
7071 let evt = unsafe { self . create_evt ( ) } ?;
7172 let completion_token =
7273 tcp4:: CompletionToken { event : evt. as_ptr ( ) , status : Status :: SUCCESS } ;
@@ -79,7 +80,7 @@ impl Tcp4 {
7980 return Err ( io:: Error :: from_raw_os_error ( r. as_usize ( ) ) ) ;
8081 }
8182
82- self . wait_for_flag ( ) ;
83+ unsafe { self . wait_or_cancel ( timeout , & mut conn_token . completion_token ) } ? ;
8384
8485 if completion_token. status . is_error ( ) {
8586 Err ( io:: Error :: from_raw_os_error ( completion_token. status . as_usize ( ) ) )
@@ -88,7 +89,7 @@ impl Tcp4 {
8889 }
8990 }
9091
91- pub ( crate ) fn write ( & self , buf : & [ u8 ] ) -> io:: Result < usize > {
92+ pub ( crate ) fn write ( & self , buf : & [ u8 ] , timeout : Option < Duration > ) -> io:: Result < usize > {
9293 let evt = unsafe { self . create_evt ( ) } ?;
9394 let completion_token =
9495 tcp4:: CompletionToken { event : evt. as_ptr ( ) , status : Status :: SUCCESS } ;
@@ -119,7 +120,7 @@ impl Tcp4 {
119120 return Err ( io:: Error :: from_raw_os_error ( r. as_usize ( ) ) ) ;
120121 }
121122
122- self . wait_for_flag ( ) ;
123+ unsafe { self . wait_or_cancel ( timeout , & mut token . completion_token ) } ? ;
123124
124125 if completion_token. status . is_error ( ) {
125126 Err ( io:: Error :: from_raw_os_error ( completion_token. status . as_usize ( ) ) )
@@ -128,7 +129,7 @@ impl Tcp4 {
128129 }
129130 }
130131
131- pub ( crate ) fn read ( & self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
132+ pub ( crate ) fn read ( & self , buf : & mut [ u8 ] , timeout : Option < Duration > ) -> io:: Result < usize > {
132133 let evt = unsafe { self . create_evt ( ) } ?;
133134 let completion_token =
134135 tcp4:: CompletionToken { event : evt. as_ptr ( ) , status : Status :: SUCCESS } ;
@@ -158,7 +159,7 @@ impl Tcp4 {
158159 return Err ( io:: Error :: from_raw_os_error ( r. as_usize ( ) ) ) ;
159160 }
160161
161- self . wait_for_flag ( ) ;
162+ unsafe { self . wait_or_cancel ( timeout , & mut token . completion_token ) } ? ;
162163
163164 if completion_token. status . is_error ( ) {
164165 Err ( io:: Error :: from_raw_os_error ( completion_token. status . as_usize ( ) ) )
@@ -167,6 +168,36 @@ impl Tcp4 {
167168 }
168169 }
169170
171+ /// # SAFETY
172+ /// Pointer to a token that has been issued by EFI_TCP4_PROTOCOL.Connect(),
173+ /// EFI_TCP4_PROTOCOL.Accept(), EFI_TCP4_PROTOCOL.Transmit() or EFI_TCP4_PROTOCOL.Receive().
174+ unsafe fn wait_or_cancel (
175+ & self ,
176+ timeout : Option < Duration > ,
177+ token : * mut tcp4:: CompletionToken ,
178+ ) -> io:: Result < ( ) > {
179+ if !self . wait_for_flag ( timeout) {
180+ let _ = unsafe { self . cancel ( token) } ;
181+ return Err ( io:: Error :: new ( io:: ErrorKind :: TimedOut , "Operation Timed out" ) ) ;
182+ }
183+
184+ Ok ( ( ) )
185+ }
186+
187+ /// # SAFETY
188+ /// Pointer to a token that has been issued by EFI_TCP4_PROTOCOL.Connect(),
189+ /// EFI_TCP4_PROTOCOL.Accept(), EFI_TCP4_PROTOCOL.Transmit() or EFI_TCP4_PROTOCOL.Receive().
190+ unsafe fn cancel ( & self , token : * mut tcp4:: CompletionToken ) -> io:: Result < ( ) > {
191+ let protocol = self . protocol . as_ptr ( ) ;
192+
193+ let r = unsafe { ( ( * protocol) . cancel ) ( protocol, token) } ;
194+ if r. is_error ( ) {
195+ return Err ( io:: Error :: from_raw_os_error ( r. as_usize ( ) ) ) ;
196+ } else {
197+ Ok ( ( ) )
198+ }
199+ }
200+
170201 unsafe fn create_evt ( & self ) -> io:: Result < helpers:: OwnedEvent > {
171202 self . flag . store ( false , Ordering :: Relaxed ) ;
172203 helpers:: OwnedEvent :: new (
@@ -177,10 +208,19 @@ impl Tcp4 {
177208 )
178209 }
179210
180- fn wait_for_flag ( & self ) {
211+ fn wait_for_flag ( & self , timeout : Option < Duration > ) -> bool {
212+ let start = Instant :: now ( ) ;
213+
181214 while !self . flag . load ( Ordering :: Relaxed ) {
182215 let _ = self . poll ( ) ;
216+ if let Some ( t) = timeout {
217+ if Instant :: now ( ) . duration_since ( start) >= t {
218+ return false ;
219+ }
220+ }
183221 }
222+
223+ true
184224 }
185225
186226 fn poll ( & self ) -> io:: Result < ( ) > {
0 commit comments