@@ -11,9 +11,10 @@ use std::{
11
11
use compio_buf:: { BufResult , IntoInner } ;
12
12
use compio_driver:: { syscall, AsRawFd , OpCode , OpType , RawFd , SharedFd , ToSharedFd } ;
13
13
use windows_sys:: Win32 :: {
14
+ Foundation :: ERROR_IO_PENDING ,
14
15
Networking :: WinSock :: {
15
- WSAEnumNetworkEvents , WSAEventSelect , FD_ACCEPT , FD_CONNECT , FD_READ , FD_WRITE ,
16
- WSANETWORKEVENTS ,
16
+ WSAEnumNetworkEvents , WSAEventSelect , FD_ACCEPT , FD_CONNECT , FD_MAX_EVENTS , FD_READ ,
17
+ FD_WRITE , WSANETWORKEVENTS ,
17
18
} ,
18
19
System :: { Threading :: CreateEventW , IO :: OVERLAPPED } ,
19
20
} ;
@@ -85,12 +86,10 @@ impl<T: AsRawFd> Deref for PollFd<T> {
85
86
}
86
87
}
87
88
88
- const EVENT_COUNT : usize = 5 ;
89
-
90
89
#[ derive( Debug ) ]
91
90
pub struct WSAEvent {
92
91
ev_object : SharedFd < OwnedHandle > ,
93
- ev_record : [ AtomicUsize ; EVENT_COUNT ] ,
92
+ ev_record : [ AtomicUsize ; FD_MAX_EVENTS as usize ] ,
94
93
events : AtomicI32 ,
95
94
}
96
95
@@ -109,7 +108,7 @@ impl WSAEvent {
109
108
110
109
pub async fn wait < T : AsRawFd + ' static > (
111
110
& self ,
112
- socket : SharedFd < T > ,
111
+ mut socket : SharedFd < T > ,
113
112
event : u32 ,
114
113
) -> io:: Result < ( ) > {
115
114
struct EventGuard < ' a > {
@@ -119,7 +118,7 @@ impl WSAEvent {
119
118
120
119
impl Drop for EventGuard < ' _ > {
121
120
fn drop ( & mut self ) {
122
- let index = ( self . event . ilog2 ( ) - 1 ) as usize ;
121
+ let index = self . event . ilog2 ( ) as usize ;
123
122
if self . wsa_event . ev_record [ index] . fetch_sub ( 1 , Ordering :: Relaxed ) == 1 {
124
123
self . wsa_event
125
124
. events
@@ -129,9 +128,9 @@ impl WSAEvent {
129
128
}
130
129
131
130
let event = event as i32 ;
132
- let ev_object = self . ev_object . clone ( ) ;
131
+ let mut ev_object = self . ev_object . clone ( ) ;
133
132
134
- let index = ( event. ilog2 ( ) - 1 ) as usize ;
133
+ let index = event. ilog2 ( ) as usize ;
135
134
let events = if self . ev_record [ index] . fetch_add ( 1 , Ordering :: Relaxed ) == 0 {
136
135
self . events . fetch_or ( event, Ordering :: Relaxed ) | event
137
136
} else {
@@ -149,25 +148,35 @@ impl WSAEvent {
149
148
wsa_event : self ,
150
149
event,
151
150
} ;
152
- let op = WaitWSAEvent :: new ( socket, ev_object, index + 1 ) ;
153
- let BufResult ( res, _) = compio_runtime:: submit ( op) . await ;
154
- res?;
155
- Ok ( ( ) )
151
+ loop {
152
+ let op = WaitWSAEvent :: new ( socket, ev_object, event) ;
153
+ let BufResult ( res, op) = compio_runtime:: submit ( op) . await ;
154
+ WaitWSAEvent {
155
+ socket,
156
+ ev_object,
157
+ ..
158
+ } = op;
159
+ match res {
160
+ Ok ( _) => break Ok ( ( ) ) ,
161
+ Err ( e) if e. kind ( ) == io:: ErrorKind :: WouldBlock => { }
162
+ Err ( e) => break Err ( e) ,
163
+ }
164
+ }
156
165
}
157
166
}
158
167
159
168
struct WaitWSAEvent < T > {
160
169
socket : SharedFd < T > ,
161
170
ev_object : SharedFd < OwnedHandle > ,
162
- index : usize ,
171
+ event : i32 ,
163
172
}
164
173
165
174
impl < T > WaitWSAEvent < T > {
166
- pub fn new ( socket : SharedFd < T > , ev_object : SharedFd < OwnedHandle > , index : usize ) -> Self {
175
+ pub fn new ( socket : SharedFd < T > , ev_object : SharedFd < OwnedHandle > , event : i32 ) -> Self {
167
176
Self {
168
177
socket,
169
178
ev_object,
170
- index ,
179
+ event ,
171
180
}
172
181
}
173
182
}
@@ -187,7 +196,6 @@ impl<T: AsRawFd> OpCode for WaitWSAEvent<T> {
187
196
188
197
unsafe fn operate ( self : Pin < & mut Self > , _optr : * mut OVERLAPPED ) -> Poll < io:: Result < usize > > {
189
198
let mut events: WSANETWORKEVENTS = unsafe { std:: mem:: zeroed ( ) } ;
190
- events. lNetworkEvents = 10 ;
191
199
syscall ! (
192
200
SOCKET ,
193
201
WSAEnumNetworkEvents (
@@ -196,7 +204,11 @@ impl<T: AsRawFd> OpCode for WaitWSAEvent<T> {
196
204
& mut events
197
205
)
198
206
) ?;
199
- let res = events. iErrorCode [ self . index + 1 ] ;
207
+ let res = if ( events. lNetworkEvents & self . event ) != 0 {
208
+ events. iErrorCode [ self . event . ilog2 ( ) as usize ]
209
+ } else {
210
+ ERROR_IO_PENDING as _
211
+ } ;
200
212
if res == 0 {
201
213
Poll :: Ready ( Ok ( 0 ) )
202
214
} else {
0 commit comments