@@ -66,7 +66,7 @@ macro_rules! impl_iocp {
6666 fn_ptr: Option <& extern "system" fn ( $( $arg_type) ,* ) -> $result>,
6767 $( $arg: $arg_type) ,*
6868 ) -> $result {
69- use $crate:: common:: constants:: { CoroutineState , SyscallName , SyscallState } ;
69+ use $crate:: common:: constants:: { CoroutineState , SyscallState } ;
7070 use $crate:: scheduler:: { SchedulableCoroutine , SchedulableSuspender } ;
7171
7272 if let Ok ( arc) = $crate:: net:: EventLoops :: $syscall( $( $arg, ) * ) {
@@ -77,9 +77,7 @@ macro_rules! impl_iocp {
7777 if co. syscall( ( ) , syscall, new_state) . is_err( ) {
7878 $crate:: error!(
7979 "{} change to syscall {} {} failed !" ,
80- co. name( ) ,
81- syscall,
82- new_state
80+ co. name( ) , syscall, new_state
8381 ) ;
8482 }
8583 }
@@ -109,11 +107,7 @@ macro_rules! impl_iocp {
109107 . expect( "no syscall result" ) ;
110108 if syscall_result < 0 {
111109 $crate:: syscall:: set_errno( ( -syscall_result) . try_into( ) . expect( "errno overflow" ) ) ;
112- if SyscallName :: accept == SyscallName :: $syscall {
113- syscall_result = 0 ;
114- } else {
115- syscall_result = -1 ;
116- }
110+ syscall_result = -1 ;
117111 }
118112 return <$result>:: try_from( syscall_result) . expect( "overflow" ) ;
119113 }
@@ -123,6 +117,150 @@ macro_rules! impl_iocp {
123117 }
124118}
125119
120+ #[ allow( unused_macros) ]
121+ macro_rules! impl_iocp_read {
122+ (
123+ $struct_name: ident, $trait_name: ident,
124+ $syscall: ident( $fd: ident : $fd_type: ty, $( $arg: ident : $arg_type: ty) ,* ) -> $result: ty
125+ ) => {
126+ #[ repr( C ) ]
127+ #[ derive( Debug , Default ) ]
128+ #[ cfg( all( windows, feature = "iocp" ) ) ]
129+ struct $struct_name<I : $trait_name> {
130+ inner: I ,
131+ }
132+
133+ #[ cfg( all( windows, feature = "iocp" ) ) ]
134+ impl <I : $trait_name> $trait_name for $struct_name<I > {
135+ extern "system" fn $syscall(
136+ & self ,
137+ fn_ptr: Option <& extern "system" fn ( $fd_type, $( $arg_type) ,* ) -> $result>,
138+ $fd: $fd_type,
139+ $( $arg: $arg_type) ,*
140+ ) -> $result {
141+ use $crate:: common:: constants:: { CoroutineState , SyscallState } ;
142+ use $crate:: scheduler:: { SchedulableCoroutine , SchedulableSuspender } ;
143+
144+ if let Ok ( arc) = $crate:: net:: EventLoops :: $syscall( $fd, $( $arg, ) * ) {
145+ if let Some ( co) = SchedulableCoroutine :: current( ) {
146+ if let CoroutineState :: Syscall ( ( ) , syscall, SyscallState :: Executing ) = co. state( )
147+ {
148+ let new_state = SyscallState :: Suspend ( $crate:: syscall:: recv_time_limit( $fd) ) ;
149+ if co. syscall( ( ) , syscall, new_state) . is_err( ) {
150+ $crate:: error!(
151+ "{} change to syscall {} {} failed !" ,
152+ co. name( ) , syscall, new_state
153+ ) ;
154+ }
155+ }
156+ }
157+ if let Some ( suspender) = SchedulableSuspender :: current( ) {
158+ suspender. suspend( ) ;
159+ //回来的时候,系统调用已经执行完了
160+ }
161+ if let Some ( co) = SchedulableCoroutine :: current( ) {
162+ if let CoroutineState :: Syscall ( ( ) , syscall, SyscallState :: Callback ) = co. state( )
163+ {
164+ let new_state = SyscallState :: Executing ;
165+ if co. syscall( ( ) , syscall, new_state) . is_err( ) {
166+ $crate:: error!(
167+ "{} change to syscall {} {} failed !" ,
168+ co. name( ) , syscall, new_state
169+ ) ;
170+ }
171+ }
172+ }
173+ let ( lock, cvar) = & * arc;
174+ let mut syscall_result = cvar
175+ . wait_while( lock. lock( ) . expect( "lock failed" ) ,
176+ |& mut result| result. is_none( )
177+ )
178+ . expect( "lock failed" )
179+ . expect( "no syscall result" ) ;
180+ if syscall_result < 0 {
181+ $crate:: syscall:: set_errno( ( -syscall_result) . try_into( ) . expect( "errno overflow" ) ) ;
182+ syscall_result = -1 ;
183+ }
184+ return <$result>:: try_from( syscall_result) . expect( "overflow" ) ;
185+ }
186+ self . inner. $syscall( fn_ptr, $fd, $( $arg, ) * )
187+ }
188+ }
189+ }
190+ }
191+
192+ #[ allow( unused_macros) ]
193+ macro_rules! impl_iocp_write {
194+ (
195+ $struct_name: ident, $trait_name: ident,
196+ $syscall: ident( $fd: ident : $fd_type: ty, $( $arg: ident : $arg_type: ty) ,* ) -> $result: ty
197+ ) => {
198+ #[ repr( C ) ]
199+ #[ derive( Debug , Default ) ]
200+ #[ cfg( all( windows, feature = "iocp" ) ) ]
201+ struct $struct_name<I : $trait_name> {
202+ inner: I ,
203+ }
204+
205+ #[ cfg( all( windows, feature = "iocp" ) ) ]
206+ impl <I : $trait_name> $trait_name for $struct_name<I > {
207+ extern "system" fn $syscall(
208+ & self ,
209+ fn_ptr: Option <& extern "system" fn ( $fd_type, $( $arg_type) ,* ) -> $result>,
210+ $fd: $fd_type,
211+ $( $arg: $arg_type) ,*
212+ ) -> $result {
213+ use $crate:: common:: constants:: { CoroutineState , SyscallState } ;
214+ use $crate:: scheduler:: { SchedulableCoroutine , SchedulableSuspender } ;
215+
216+ if let Ok ( arc) = $crate:: net:: EventLoops :: $syscall( $fd, $( $arg, ) * ) {
217+ if let Some ( co) = SchedulableCoroutine :: current( ) {
218+ if let CoroutineState :: Syscall ( ( ) , syscall, SyscallState :: Executing ) = co. state( )
219+ {
220+ let new_state = SyscallState :: Suspend ( $crate:: syscall:: send_time_limit( $fd) ) ;
221+ if co. syscall( ( ) , syscall, new_state) . is_err( ) {
222+ $crate:: error!(
223+ "{} change to syscall {} {} failed !" ,
224+ co. name( ) , syscall, new_state
225+ ) ;
226+ }
227+ }
228+ }
229+ if let Some ( suspender) = SchedulableSuspender :: current( ) {
230+ suspender. suspend( ) ;
231+ //回来的时候,系统调用已经执行完了
232+ }
233+ if let Some ( co) = SchedulableCoroutine :: current( ) {
234+ if let CoroutineState :: Syscall ( ( ) , syscall, SyscallState :: Callback ) = co. state( )
235+ {
236+ let new_state = SyscallState :: Executing ;
237+ if co. syscall( ( ) , syscall, new_state) . is_err( ) {
238+ $crate:: error!(
239+ "{} change to syscall {} {} failed !" ,
240+ co. name( ) , syscall, new_state
241+ ) ;
242+ }
243+ }
244+ }
245+ let ( lock, cvar) = & * arc;
246+ let mut syscall_result = cvar
247+ . wait_while( lock. lock( ) . expect( "lock failed" ) ,
248+ |& mut result| result. is_none( )
249+ )
250+ . expect( "lock failed" )
251+ . expect( "no syscall result" ) ;
252+ if syscall_result < 0 {
253+ $crate:: syscall:: set_errno( ( -syscall_result) . try_into( ) . expect( "errno overflow" ) ) ;
254+ syscall_result = -1 ;
255+ }
256+ return <$result>:: try_from( syscall_result) . expect( "overflow" ) ;
257+ }
258+ self . inner. $syscall( fn_ptr, $fd, $( $arg, ) * )
259+ }
260+ }
261+ }
262+ }
263+
126264macro_rules! impl_nio_read {
127265 (
128266 $struct_name: ident, $trait_name: ident,
0 commit comments