@@ -6,6 +6,7 @@ use crate::net::SocketAddrV4;
6
6
use crate :: ptr:: NonNull ;
7
7
use crate :: sync:: atomic:: { AtomicBool , Ordering } ;
8
8
use crate :: sys:: pal:: helpers;
9
+ use crate :: time:: { Duration , Instant } ;
9
10
10
11
const TYPE_OF_SERVICE : u8 = 8 ;
11
12
const TIME_TO_LIVE : u8 = 255 ;
@@ -66,7 +67,7 @@ impl Tcp4 {
66
67
if r. is_error ( ) { Err ( crate :: io:: Error :: from_raw_os_error ( r. as_usize ( ) ) ) } else { Ok ( ( ) ) }
67
68
}
68
69
69
- pub ( crate ) fn connect ( & self ) -> io:: Result < ( ) > {
70
+ pub ( crate ) fn connect ( & self , timeout : Option < Duration > ) -> io:: Result < ( ) > {
70
71
let evt = unsafe { self . create_evt ( ) } ?;
71
72
let completion_token =
72
73
tcp4:: CompletionToken { event : evt. as_ptr ( ) , status : Status :: SUCCESS } ;
@@ -79,7 +80,7 @@ impl Tcp4 {
79
80
return Err ( io:: Error :: from_raw_os_error ( r. as_usize ( ) ) ) ;
80
81
}
81
82
82
- self . wait_for_flag ( ) ;
83
+ unsafe { self . wait_or_cancel ( timeout , & mut conn_token . completion_token ) } ? ;
83
84
84
85
if completion_token. status . is_error ( ) {
85
86
Err ( io:: Error :: from_raw_os_error ( completion_token. status . as_usize ( ) ) )
@@ -88,7 +89,7 @@ impl Tcp4 {
88
89
}
89
90
}
90
91
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 > {
92
93
let evt = unsafe { self . create_evt ( ) } ?;
93
94
let completion_token =
94
95
tcp4:: CompletionToken { event : evt. as_ptr ( ) , status : Status :: SUCCESS } ;
@@ -119,7 +120,7 @@ impl Tcp4 {
119
120
return Err ( io:: Error :: from_raw_os_error ( r. as_usize ( ) ) ) ;
120
121
}
121
122
122
- self . wait_for_flag ( ) ;
123
+ unsafe { self . wait_or_cancel ( timeout , & mut token . completion_token ) } ? ;
123
124
124
125
if completion_token. status . is_error ( ) {
125
126
Err ( io:: Error :: from_raw_os_error ( completion_token. status . as_usize ( ) ) )
@@ -128,7 +129,7 @@ impl Tcp4 {
128
129
}
129
130
}
130
131
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 > {
132
133
let evt = unsafe { self . create_evt ( ) } ?;
133
134
let completion_token =
134
135
tcp4:: CompletionToken { event : evt. as_ptr ( ) , status : Status :: SUCCESS } ;
@@ -158,7 +159,7 @@ impl Tcp4 {
158
159
return Err ( io:: Error :: from_raw_os_error ( r. as_usize ( ) ) ) ;
159
160
}
160
161
161
- self . wait_for_flag ( ) ;
162
+ unsafe { self . wait_or_cancel ( timeout , & mut token . completion_token ) } ? ;
162
163
163
164
if completion_token. status . is_error ( ) {
164
165
Err ( io:: Error :: from_raw_os_error ( completion_token. status . as_usize ( ) ) )
@@ -167,6 +168,36 @@ impl Tcp4 {
167
168
}
168
169
}
169
170
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
+
170
201
unsafe fn create_evt ( & self ) -> io:: Result < helpers:: OwnedEvent > {
171
202
self . flag . store ( false , Ordering :: Relaxed ) ;
172
203
helpers:: OwnedEvent :: new (
@@ -177,10 +208,19 @@ impl Tcp4 {
177
208
)
178
209
}
179
210
180
- fn wait_for_flag ( & self ) {
211
+ fn wait_for_flag ( & self , timeout : Option < Duration > ) -> bool {
212
+ let start = Instant :: now ( ) ;
213
+
181
214
while !self . flag . load ( Ordering :: Relaxed ) {
182
215
let _ = self . poll ( ) ;
216
+ if let Some ( t) = timeout {
217
+ if Instant :: now ( ) . duration_since ( start) >= t {
218
+ return false ;
219
+ }
220
+ }
183
221
}
222
+
223
+ true
184
224
}
185
225
186
226
fn poll ( & self ) -> io:: Result < ( ) > {
0 commit comments