@@ -73,7 +73,7 @@ macro_rules! impl_io_uring {
7373 }
7474 if let Some ( suspender) = SchedulableSuspender :: current( ) {
7575 suspender. suspend( ) ;
76- //回来的时候,系统调用已经执行完了
76+ //回来的时候,系统调用已经执行完毕
7777 }
7878 if let Some ( co) = SchedulableCoroutine :: current( ) {
7979 if let CoroutineState :: Syscall ( ( ) , syscall, SyscallState :: Callback ) = co. state( )
@@ -110,6 +110,172 @@ macro_rules! impl_io_uring {
110110 }
111111}
112112
113+ macro_rules! impl_io_uring_read {
114+ ( $struct_name: ident, $trait_name: ident, $syscall: ident( $fd: ident : $fd_type: ty, $( $arg: ident : $arg_type: ty) ,* ) -> $result: ty ) => {
115+ #[ repr( C ) ]
116+ #[ derive( Debug , Default ) ]
117+ #[ cfg( all( target_os = "linux" , feature = "io_uring" ) ) ]
118+ struct $struct_name<I : $trait_name> {
119+ inner: I ,
120+ }
121+
122+ #[ cfg( all( target_os = "linux" , feature = "io_uring" ) ) ]
123+ impl <I : $trait_name> $trait_name for $struct_name<I > {
124+ extern "C" fn $syscall(
125+ & self ,
126+ fn_ptr: Option <& extern "C" fn ( $fd_type, $( $arg_type) ,* ) -> $result>,
127+ $fd: $fd_type,
128+ $( $arg: $arg_type) ,*
129+ ) -> $result {
130+ if let Ok ( arc) = $crate:: net:: EventLoops :: $syscall( $( $arg, ) * ) {
131+ use $crate:: common:: constants:: { CoroutineState , SyscallState } ;
132+ use $crate:: scheduler:: { SchedulableCoroutine , SchedulableSuspender } ;
133+
134+ if let Some ( co) = SchedulableCoroutine :: current( ) {
135+ if let CoroutineState :: Syscall ( ( ) , syscall, SyscallState :: Executing ) = co. state( )
136+ {
137+ let new_state = SyscallState :: Suspend (
138+ $crate:: common:: now( )
139+ . saturating_add( $crate:: syscall:: recv_time_limit( $fd) )
140+ ) ;
141+ if co. syscall( ( ) , syscall, new_state) . is_err( ) {
142+ $crate:: error!(
143+ "{} change to syscall {} {} failed !" ,
144+ co. name( ) , syscall, new_state
145+ ) ;
146+ }
147+ }
148+ }
149+ if let Some ( suspender) = SchedulableSuspender :: current( ) {
150+ suspender. suspend( ) ;
151+ //回来的时候,系统调用已经执行完毕或者超时
152+ }
153+ if let Some ( co) = SchedulableCoroutine :: current( ) {
154+ if let CoroutineState :: Syscall ( ( ) , syscall, syscall_state) = co. state( ) {
155+ match syscall_state {
156+ SyscallState :: Timeout => {
157+ $crate:: syscall:: set_errno( libc:: ETIMEDOUT ) ;
158+ return -1 ;
159+ } ,
160+ SyscallState :: Callback => {
161+ let new_state = SyscallState :: Executing ;
162+ if co. syscall( ( ) , syscall, new_state) . is_err( ) {
163+ $crate:: error!(
164+ "{} change to syscall {} {} failed !" ,
165+ co. name( ) , syscall, new_state
166+ ) ;
167+ }
168+ } ,
169+ _ => { }
170+ }
171+ }
172+ }
173+ let ( lock, cvar) = & * arc;
174+ let mut syscall_result: $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+ . try_into( )
181+ . expect( "io_uring syscall result overflow" ) ;
182+ if syscall_result < 0 {
183+ let errno: std:: ffi:: c_int = ( -syscall_result) . try_into( )
184+ . expect( "io_uring errno overflow" ) ;
185+ $crate:: syscall:: set_errno( errno) ;
186+ syscall_result = -1 ;
187+ }
188+ return syscall_result;
189+ }
190+ self . inner. $syscall( fn_ptr, $( $arg, ) * )
191+ }
192+ }
193+ }
194+ }
195+
196+ macro_rules! impl_io_uring_write {
197+ ( $struct_name: ident, $trait_name: ident, $syscall: ident( $fd: ident : $fd_type: ty, $( $arg: ident : $arg_type: ty) ,* ) -> $result: ty ) => {
198+ #[ repr( C ) ]
199+ #[ derive( Debug , Default ) ]
200+ #[ cfg( all( target_os = "linux" , feature = "io_uring" ) ) ]
201+ struct $struct_name<I : $trait_name> {
202+ inner: I ,
203+ }
204+
205+ #[ cfg( all( target_os = "linux" , feature = "io_uring" ) ) ]
206+ impl <I : $trait_name> $trait_name for $struct_name<I > {
207+ extern "C" fn $syscall(
208+ & self ,
209+ fn_ptr: Option <& extern "C" fn ( $fd_type, $( $arg_type) ,* ) -> $result>,
210+ $fd: $fd_type,
211+ $( $arg: $arg_type) ,*
212+ ) -> $result {
213+ if let Ok ( arc) = $crate:: net:: EventLoops :: $syscall( $( $arg, ) * ) {
214+ use $crate:: common:: constants:: { CoroutineState , SyscallState } ;
215+ use $crate:: scheduler:: { SchedulableCoroutine , SchedulableSuspender } ;
216+
217+ if let Some ( co) = SchedulableCoroutine :: current( ) {
218+ if let CoroutineState :: Syscall ( ( ) , syscall, SyscallState :: Executing ) = co. state( )
219+ {
220+ let new_state = SyscallState :: Suspend (
221+ $crate:: common:: now( )
222+ . saturating_add( $crate:: syscall:: send_time_limit( $fd) )
223+ ) ;
224+ if co. syscall( ( ) , syscall, new_state) . is_err( ) {
225+ $crate:: error!(
226+ "{} change to syscall {} {} failed !" ,
227+ co. name( ) , syscall, new_state
228+ ) ;
229+ }
230+ }
231+ }
232+ if let Some ( suspender) = SchedulableSuspender :: current( ) {
233+ suspender. suspend( ) ;
234+ //回来的时候,系统调用已经执行完毕或者超时
235+ }
236+ if let Some ( co) = SchedulableCoroutine :: current( ) {
237+ if let CoroutineState :: Syscall ( ( ) , syscall, syscall_state) = co. state( ) {
238+ match syscall_state {
239+ SyscallState :: Timeout => {
240+ $crate:: syscall:: set_errno( libc:: ETIMEDOUT ) ;
241+ return -1 ;
242+ } ,
243+ SyscallState :: Callback => {
244+ let new_state = SyscallState :: Executing ;
245+ if co. syscall( ( ) , syscall, new_state) . is_err( ) {
246+ $crate:: error!(
247+ "{} change to syscall {} {} failed !" ,
248+ co. name( ) , syscall, new_state
249+ ) ;
250+ }
251+ } ,
252+ _ => { }
253+ }
254+ }
255+ }
256+ let ( lock, cvar) = & * arc;
257+ let mut syscall_result: $result = cvar
258+ . wait_while( lock. lock( ) . expect( "lock failed" ) ,
259+ |& mut result| result. is_none( )
260+ )
261+ . expect( "lock failed" )
262+ . expect( "no syscall result" )
263+ . try_into( )
264+ . expect( "io_uring syscall result overflow" ) ;
265+ if syscall_result < 0 {
266+ let errno: std:: ffi:: c_int = ( -syscall_result) . try_into( )
267+ . expect( "io_uring errno overflow" ) ;
268+ $crate:: syscall:: set_errno( errno) ;
269+ syscall_result = -1 ;
270+ }
271+ return syscall_result;
272+ }
273+ self . inner. $syscall( fn_ptr, $( $arg, ) * )
274+ }
275+ }
276+ }
277+ }
278+
113279macro_rules! impl_nio_read {
114280 ( $struct_name: ident, $trait_name: ident, $syscall: ident( $fd: ident : $fd_type: ty, $( $arg: ident : $arg_type: ty) ,* ) -> $result: ty ) => {
115281 #[ repr( C ) ]
0 commit comments