diff --git a/examples/src/lib.rs b/examples/src/lib.rs index 173fe08e..604c5ac0 100644 --- a/examples/src/lib.rs +++ b/examples/src/lib.rs @@ -14,52 +14,61 @@ fn crate_task(input: i32) { ); } -pub fn start_server( - addr: A, - server_finished: Arc<(Mutex, Condvar)>, -) -> std::io::Result<()> { - let listener = TcpListener::bind(addr)?; +pub fn start_server(addr: A, server_finished: Arc<(Mutex, Condvar)>) { + let listener = TcpListener::bind(addr).expect("start server failed"); for stream in listener.incoming() { - let mut stream = stream?; + let mut socket = stream.expect("accept new connection failed"); let mut buffer1 = [0; 256]; for _ in 0..3 { - assert_eq!(12, stream.read(&mut buffer1)?); + assert_eq!(12, socket.read(&mut buffer1).expect("recv failed")); println!("Server Received: {}", String::from_utf8_lossy(&buffer1)); - assert_eq!(256, stream.write(&buffer1)?); + assert_eq!(256, socket.write(&buffer1).expect("send failed")); println!("Server Send"); } let mut buffer2 = [0; 256]; for _ in 0..3 { let mut buffers = [IoSliceMut::new(&mut buffer1), IoSliceMut::new(&mut buffer2)]; - assert_eq!(26, stream.read_vectored(&mut buffers)?); + assert_eq!( + 26, + socket.read_vectored(&mut buffers).expect("readv failed") + ); println!( "Server Received Multiple: {}{}", String::from_utf8_lossy(&buffer1), String::from_utf8_lossy(&buffer2) ); let responses = [IoSlice::new(&buffer1), IoSlice::new(&buffer2)]; - assert_eq!(512, stream.write_vectored(&responses)?); + assert_eq!( + 512, + socket.write_vectored(&responses).expect("writev failed") + ); println!("Server Send Multiple"); } println!("Server Shutdown Write"); - stream.shutdown(Shutdown::Write).map(|()| { + if socket.shutdown(Shutdown::Write).is_ok() { println!("Server Closed Connection"); - })?; - let (lock, cvar) = &*server_finished; - let mut pending = lock.lock().unwrap(); - *pending = false; - cvar.notify_one(); + let (lock, cvar) = &*server_finished; + let mut pending = lock.lock().unwrap(); + *pending = false; + cvar.notify_one(); + println!("Server Closed"); + return; + } } - Ok(()) } -pub fn start_client(addr: A) -> std::io::Result<()> { - let mut stream = connect_timeout(addr, Duration::from_secs(3))?; +pub fn start_client(addr: A) { + let mut stream = connect_timeout(addr, Duration::from_secs(3)).expect("connect failed"); let mut buffer1 = [0; 256]; for i in 0..3 { - assert_eq!(12, stream.write(format!("RequestPart{i}").as_ref())?); + assert_eq!( + 12, + stream + .write(format!("RequestPart{i}").as_ref()) + .expect("send failed") + ); println!("Client Send"); - assert_eq!(256, stream.read(&mut buffer1)?); + assert_eq!(256, stream.read(&mut buffer1).expect("recv failed")); println!("Client Received: {}", String::from_utf8_lossy(&buffer1)); } let mut buffer2 = [0; 256]; @@ -70,10 +79,13 @@ pub fn start_client(addr: A) -> std::io::Result<()> { IoSlice::new(request1.as_ref()), IoSlice::new(request2.as_ref()), ]; - assert_eq!(26, stream.write_vectored(&requests)?); + assert_eq!(26, stream.write_vectored(&requests).expect("writev failed")); println!("Client Send Multiple"); let mut buffers = [IoSliceMut::new(&mut buffer1), IoSliceMut::new(&mut buffer2)]; - assert_eq!(512, stream.read_vectored(&mut buffers)?); + assert_eq!( + 512, + stream.read_vectored(&mut buffers).expect("readv failed") + ); println!( "Client Received Multiple: {}{}", String::from_utf8_lossy(&buffer1), @@ -81,9 +93,8 @@ pub fn start_client(addr: A) -> std::io::Result<()> { ); } println!("Client Shutdown Write"); - stream.shutdown(Shutdown::Write).map(|()| { - println!("Client Closed"); - }) + stream.shutdown(Shutdown::Write).expect("shutdown failed"); + println!("Client Closed"); } fn connect_timeout(addr: A, timeout: Duration) -> std::io::Result { @@ -111,7 +122,7 @@ pub fn crate_server( crate_task(1); let mut data: [u8; 512] = unsafe { std::mem::zeroed() }; data[511] = b'\n'; - let listener = TcpListener::bind(format!("127.0.0.1:{port}")) + let listener = TcpListener::bind((IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), port)) .unwrap_or_else(|_| panic!("bind to 127.0.0.1:{port} failed !")); server_started.store(true, Ordering::Release); //invoke by libc::accept @@ -205,7 +216,7 @@ pub fn crate_co_server( crate_task(11); let mut data: [u8; 512] = unsafe { std::mem::zeroed() }; data[511] = b'\n'; - let listener = TcpListener::bind(format!("127.0.0.1:{port}")) + let listener = TcpListener::bind((IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), port)) .unwrap_or_else(|_| panic!("bind to 127.0.0.1:{port} failed !")); server_started.store(true, Ordering::Release); //invoke by libc::accept diff --git a/open-coroutine-core/src/net/selector/mod.rs b/open-coroutine-core/src/net/selector/mod.rs index 2fb174a1..258ae424 100644 --- a/open-coroutine-core/src/net/selector/mod.rs +++ b/open-coroutine-core/src/net/selector/mod.rs @@ -132,10 +132,7 @@ pub(crate) trait Selector> { READABLE_RECORDS.remove(&fd).is_some(), "Clean READABLE_RECORDS failed !" ); - assert!( - READABLE_TOKEN_RECORDS.remove(&fd).is_some(), - "Clean READABLE_TOKEN_RECORDS failed !" - ); + _ = READABLE_TOKEN_RECORDS.remove(&fd); } else { self.del_event(fd)?; } @@ -158,10 +155,7 @@ pub(crate) trait Selector> { WRITABLE_RECORDS.remove(&fd).is_some(), "Clean WRITABLE_RECORDS failed !" ); - assert!( - WRITABLE_TOKEN_RECORDS.remove(&fd).is_some(), - "Clean WRITABLE_TOKEN_RECORDS failed !" - ); + _ = WRITABLE_TOKEN_RECORDS.remove(&fd); } else { self.del_event(fd)?; } diff --git a/open-coroutine-core/src/syscall/facade.rs b/open-coroutine-core/src/syscall/facade.rs index e6cf6f83..3f558077 100644 --- a/open-coroutine-core/src/syscall/facade.rs +++ b/open-coroutine-core/src/syscall/facade.rs @@ -87,16 +87,6 @@ pub extern "C" fn pread( CHAIN.pread(fn_ptr, fd, buf, count, offset) } -#[must_use] -pub extern "C" fn readv( - fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int) -> ssize_t>, - fd: c_int, - iov: *const iovec, - iovcnt: c_int, -) -> ssize_t { - CHAIN.readv(fn_ptr, fd, iov, iovcnt) -} - #[must_use] pub extern "C" fn preadv( fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int, off_t) -> ssize_t>, @@ -156,16 +146,6 @@ pub extern "C" fn pwrite( CHAIN.pwrite(fn_ptr, fd, buf, count, offset) } -#[must_use] -pub extern "C" fn writev( - fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int) -> ssize_t>, - fd: c_int, - iov: *const iovec, - iovcnt: c_int, -) -> ssize_t { - CHAIN.writev(fn_ptr, fd, iov, iovcnt) -} - #[must_use] pub extern "C" fn pwritev( fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int, off_t) -> ssize_t>, diff --git a/open-coroutine-core/src/syscall/io_uring.rs b/open-coroutine-core/src/syscall/io_uring.rs index fda70988..250ebcc8 100644 --- a/open-coroutine-core/src/syscall/io_uring.rs +++ b/open-coroutine-core/src/syscall/io_uring.rs @@ -94,16 +94,6 @@ impl UnixSyscall for IoUringLinuxSyscall { impl_io_uring!(self, pread, fn_ptr, fd, buf, count, offset) } - extern "C" fn readv( - &self, - fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int) -> ssize_t>, - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - ) -> ssize_t { - impl_io_uring!(self, readv, fn_ptr, fd, iov, iovcnt) - } - extern "C" fn preadv( &self, fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int, off_t) -> ssize_t>, @@ -168,16 +158,6 @@ impl UnixSyscall for IoUringLinuxSyscall { impl_io_uring!(self, pwrite, fn_ptr, fd, buf, count, offset) } - extern "C" fn writev( - &self, - fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int) -> ssize_t>, - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - ) -> ssize_t { - impl_io_uring!(self, writev, fn_ptr, fd, iov, iovcnt) - } - extern "C" fn pwritev( &self, fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int, off_t) -> ssize_t>, diff --git a/open-coroutine-core/src/syscall/mod.rs b/open-coroutine-core/src/syscall/mod.rs index d2f2f73f..b0062cbc 100644 --- a/open-coroutine-core/src/syscall/mod.rs +++ b/open-coroutine-core/src/syscall/mod.rs @@ -91,14 +91,6 @@ pub trait UnixSyscall { offset: off_t, ) -> ssize_t; - extern "C" fn readv( - &self, - fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int) -> ssize_t>, - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - ) -> ssize_t; - extern "C" fn preadv( &self, fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int, off_t) -> ssize_t>, @@ -155,14 +147,6 @@ pub trait UnixSyscall { offset: off_t, ) -> ssize_t; - extern "C" fn writev( - &self, - fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int) -> ssize_t>, - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - ) -> ssize_t; - extern "C" fn pwritev( &self, fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int, off_t) -> ssize_t>, diff --git a/open-coroutine-core/src/syscall/nio.rs b/open-coroutine-core/src/syscall/nio.rs index 67032e6e..1c11674e 100644 --- a/open-coroutine-core/src/syscall/nio.rs +++ b/open-coroutine-core/src/syscall/nio.rs @@ -397,16 +397,6 @@ impl UnixSyscall for NioLinuxSyscall { impl_expected_read_hook!(self.inner, pread, fn_ptr, fd, buf, count, offset) } - extern "C" fn readv( - &self, - fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int) -> ssize_t>, - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - ) -> ssize_t { - impl_expected_batch_read_hook!(self.inner, readv, fn_ptr, fd, iov, iovcnt,) - } - extern "C" fn preadv( &self, fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int, off_t) -> ssize_t>, @@ -561,16 +551,6 @@ impl UnixSyscall for NioLinuxSyscall { impl_expected_write_hook!(self.inner, pwrite, fn_ptr, fd, buf, count, offset) } - extern "C" fn writev( - &self, - fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int) -> ssize_t>, - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - ) -> ssize_t { - impl_expected_batch_write_hook!(self.inner, writev, fn_ptr, fd, iov, iovcnt,) - } - extern "C" fn pwritev( &self, fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int, off_t) -> ssize_t>, diff --git a/open-coroutine-core/src/syscall/raw.rs b/open-coroutine-core/src/syscall/raw.rs index 980ddec1..9f85b638 100644 --- a/open-coroutine-core/src/syscall/raw.rs +++ b/open-coroutine-core/src/syscall/raw.rs @@ -103,20 +103,6 @@ impl UnixSyscall for RawLinuxSyscall { } } - extern "C" fn readv( - &self, - fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int) -> ssize_t>, - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - ) -> ssize_t { - if let Some(f) = fn_ptr { - (f)(fd, iov, iovcnt) - } else { - unsafe { libc::readv(fd, iov, iovcnt) } - } - } - extern "C" fn preadv( &self, fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int, off_t) -> ssize_t>, @@ -203,20 +189,6 @@ impl UnixSyscall for RawLinuxSyscall { } } - extern "C" fn writev( - &self, - fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int) -> ssize_t>, - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - ) -> ssize_t { - if let Some(f) = fn_ptr { - (f)(fd, iov, iovcnt) - } else { - unsafe { libc::writev(fd, iov, iovcnt) } - } - } - extern "C" fn pwritev( &self, fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int, off_t) -> ssize_t>, diff --git a/open-coroutine-core/src/syscall/state.rs b/open-coroutine-core/src/syscall/state.rs index e5e0d958..47487bab 100644 --- a/open-coroutine-core/src/syscall/state.rs +++ b/open-coroutine-core/src/syscall/state.rs @@ -104,16 +104,6 @@ impl UnixSyscall for StateLinuxSyscall { syscall_state!(self, pread, fn_ptr, fd, buf, count, offset) } - extern "C" fn readv( - &self, - fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int) -> ssize_t>, - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - ) -> ssize_t { - syscall_state!(self, readv, fn_ptr, fd, iov, iovcnt) - } - extern "C" fn preadv( &self, fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int, off_t) -> ssize_t>, @@ -178,16 +168,6 @@ impl UnixSyscall for StateLinuxSyscall { syscall_state!(self, pwrite, fn_ptr, fd, buf, count, offset) } - extern "C" fn writev( - &self, - fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int) -> ssize_t>, - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - ) -> ssize_t { - syscall_state!(self, writev, fn_ptr, fd, iov, iovcnt) - } - extern "C" fn pwritev( &self, fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int, off_t) -> ssize_t>, diff --git a/open-coroutine-core/src/syscall/unix/mod.rs b/open-coroutine-core/src/syscall/unix/mod.rs index 04489f80..0b0d9d0f 100644 --- a/open-coroutine-core/src/syscall/unix/mod.rs +++ b/open-coroutine-core/src/syscall/unix/mod.rs @@ -5,12 +5,14 @@ pub use close::close; pub use connect::connect; pub use listen::listen; pub use nanosleep::nanosleep; +pub use readv::readv; pub use recv::recv; pub use send::send; pub use shutdown::shutdown; pub use sleep::sleep; pub use socket::socket; pub use usleep::usleep; +pub use writev::writev; macro_rules! impl_facade { ( $struct_name:ident, $trait_name: ident, $syscall: ident($($arg: ident : $arg_type: ty),*) -> $result: ty ) => { @@ -119,7 +121,7 @@ macro_rules! impl_nio_read { } } -macro_rules! impl_nio_expected_read { +macro_rules! impl_nio_read_buf { ( $struct_name:ident, $trait_name: ident, $syscall: ident($fd: ident : $fd_type: ty, $buf: ident : $buf_type: ty, $len: ident : $len_type: ty, $($arg: ident : $arg_type: ty),*) -> $result: ty ) => { #[derive(Debug, Default)] @@ -146,7 +148,7 @@ macro_rules! impl_nio_expected_read { r = self.inner.$syscall( fn_ptr, $fd, - ($buf as usize + received) as *mut c_void, + ($buf as usize + received) as *mut std::ffi::c_void, $len - received, $($arg, )* ); @@ -182,7 +184,110 @@ macro_rules! impl_nio_expected_read { } } -macro_rules! impl_nio_expected_write { +macro_rules! impl_nio_read_iovec { + ( $struct_name:ident, $trait_name: ident, $syscall: ident($fd: ident : $fd_type: ty, + $iov: ident : $iov_type: ty, $iovcnt: ident : $iovcnt_type: ty, $($arg: ident : $arg_type: ty),*) -> $result: ty ) => { + #[derive(Debug, Default)] + struct $struct_name { + inner: I, + } + + impl $trait_name for $struct_name { + extern "C" fn $syscall( + &self, + fn_ptr: Option<&extern "C" fn($fd_type, $iov_type, $iovcnt_type, $($arg_type),*) -> $result>, + $fd: $fd_type, + $iov: $iov_type, + $iovcnt: $iovcnt_type, + $($arg: $arg_type),* + ) -> $result { + let blocking = $crate::syscall::common::is_blocking($fd); + if blocking { + $crate::syscall::common::set_non_blocking($fd); + } + let vec = unsafe { Vec::from_raw_parts($iov.cast_mut(), $iovcnt as usize, $iovcnt as usize) }; + let mut length = 0; + let mut received = 0usize; + let mut r = 0; + let mut index = 0; + for iovec in &vec { + let mut offset = received.saturating_sub(length); + length += iovec.iov_len; + if received > length { + index += 1; + continue; + } + let mut arg = Vec::new(); + for i in vec.iter().skip(index) { + arg.push(*i); + } + while received < length { + if 0 != offset { + arg[0] = libc::iovec { + iov_base: (arg[0].iov_base as usize + offset) as *mut std::ffi::c_void, + iov_len: arg[0].iov_len - offset, + }; + } + r = self.inner.$syscall( + fn_ptr, + $fd, + arg.as_ptr(), + c_int::try_from(arg.len()).unwrap_or_else(|_| { + panic!("{} iovcnt overflow", $crate::constants::Syscall::$syscall) + }), + $($arg, )* + ); + if r == 0 { + std::mem::forget(vec); + if blocking { + $crate::syscall::common::set_blocking($fd); + } + return r; + } else if r != -1 { + $crate::syscall::common::reset_errno(); + received += r as usize; + if received >= length { + r = received as ssize_t; + break; + } + offset = received.saturating_sub(length); + } + let error_kind = std::io::Error::last_os_error().kind(); + if error_kind == std::io::ErrorKind::WouldBlock { + //wait read event + if $crate::net::event_loop::EventLoops::wait_read_event( + $fd, + Some(std::time::Duration::from_millis(10)) + ).is_err() { + std::mem::forget(vec); + if blocking { + $crate::syscall::common::set_blocking($fd); + } + return r; + } + } else if error_kind != std::io::ErrorKind::Interrupted { + std::mem::forget(vec); + if blocking { + $crate::syscall::common::set_blocking($fd); + } + return r; + } + } + if received >= length { + index += 1; + } + } + std::mem::forget(vec); + if blocking { + $crate::syscall::common::set_blocking($fd); + } + r + } + } + } +} + +macro_rules! impl_nio_write_buf { ( $struct_name:ident, $trait_name: ident, $syscall: ident($fd: ident : $fd_type: ty, $buf: ident : $buf_type: ty, $len: ident : $len_type: ty, $($arg: ident : $arg_type: ty),*) -> $result: ty ) => { #[derive(Debug, Default)] @@ -209,7 +314,7 @@ macro_rules! impl_nio_expected_write { r = self.inner.$syscall( fn_ptr, $fd, - ($buf as usize + sent) as *const c_void, + ($buf as usize + sent) as *const std::ffi::c_void, $len - sent, $($arg, )* ); @@ -245,6 +350,103 @@ macro_rules! impl_nio_expected_write { } } +macro_rules! impl_nio_write_iovec { + ( $struct_name:ident, $trait_name: ident, $syscall: ident($fd: ident : $fd_type: ty, + $iov: ident : $iov_type: ty, $iovcnt: ident : $iovcnt_type: ty, $($arg: ident : $arg_type: ty),*) -> $result: ty ) => { + #[derive(Debug, Default)] + struct $struct_name { + inner: I, + } + + impl $trait_name for $struct_name { + extern "C" fn $syscall( + &self, + fn_ptr: Option<&extern "C" fn($fd_type, $iov_type, $iovcnt_type, $($arg_type),*) -> $result>, + $fd: $fd_type, + $iov: $iov_type, + $iovcnt: $iovcnt_type, + $($arg: $arg_type),* + ) -> $result { + let blocking = $crate::syscall::common::is_blocking($fd); + if blocking { + $crate::syscall::common::set_non_blocking($fd); + } + let vec = unsafe { Vec::from_raw_parts($iov.cast_mut(), $iovcnt as usize, $iovcnt as usize) }; + let mut length = 0; + let mut sent = 0usize; + let mut r = 0; + let mut index = 0; + for iovec in &vec { + let mut offset = sent.saturating_sub(length); + length += iovec.iov_len; + if sent > length { + index += 1; + continue; + } + let mut arg = Vec::new(); + for i in vec.iter().skip(index) { + arg.push(*i); + } + while sent < length { + if 0 != offset { + arg[0] = libc::iovec { + iov_base: (arg[0].iov_base as usize + offset) as *mut std::ffi::c_void, + iov_len: arg[0].iov_len - offset, + }; + } + r = self.inner.$syscall( + fn_ptr, + $fd, + arg.as_ptr(), + c_int::try_from(arg.len()).unwrap_or_else(|_| { + panic!("{} iovcnt overflow", $crate::constants::Syscall::$syscall) + }), + $($arg, )* + ); + if r != -1 { + $crate::syscall::common::reset_errno(); + sent += r as usize; + if sent >= length { + r = sent as ssize_t; + break; + } + offset = sent.saturating_sub(length); + } + let error_kind = std::io::Error::last_os_error().kind(); + if error_kind == std::io::ErrorKind::WouldBlock { + //wait write event + if $crate::net::event_loop::EventLoops::wait_write_event( + $fd, + Some(std::time::Duration::from_millis(10)) + ).is_err() { + std::mem::forget(vec); + if blocking { + $crate::syscall::common::set_blocking($fd); + } + return r; + } + } else if error_kind != std::io::ErrorKind::Interrupted { + std::mem::forget(vec); + if blocking { + $crate::syscall::common::set_blocking($fd); + } + return r; + } + } + if sent >= length { + index += 1; + } + } + std::mem::forget(vec); + if blocking { + $crate::syscall::common::set_blocking($fd); + } + r + } + } + } +} + macro_rules! impl_raw { ( $struct_name: ident, $trait_name: ident, $syscall: ident($($arg: ident : $arg_type: ty),*) -> $result: ty ) => { #[derive(Debug, Copy, Clone, Default)] @@ -273,9 +475,11 @@ mod close; mod connect; mod listen; mod nanosleep; +mod readv; mod recv; mod send; mod shutdown; mod sleep; mod socket; mod usleep; +mod writev; diff --git a/open-coroutine-core/src/syscall/unix/readv.rs b/open-coroutine-core/src/syscall/unix/readv.rs new file mode 100644 index 00000000..376d1d7b --- /dev/null +++ b/open-coroutine-core/src/syscall/unix/readv.rs @@ -0,0 +1,49 @@ +use libc::{iovec, ssize_t}; +use once_cell::sync::Lazy; +use std::ffi::c_int; + +#[must_use] +pub extern "C" fn readv( + fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int) -> ssize_t>, + fd: c_int, + iov: *const iovec, + iovcnt: c_int, +) -> ssize_t { + cfg_if::cfg_if! { + if #[cfg(all(target_os = "linux", feature = "io_uring"))] { + static CHAIN: Lazy< + ReadvSyscallFacade>> + > = Lazy::new(Default::default); + } else { + static CHAIN: Lazy>> = + Lazy::new(Default::default); + } + } + CHAIN.readv(fn_ptr, fd, iov, iovcnt) +} + +trait ReadvSyscall { + extern "C" fn readv( + &self, + fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int) -> ssize_t>, + fd: c_int, + iov: *const iovec, + iovcnt: c_int, + ) -> ssize_t; +} + +impl_facade!(ReadvSyscallFacade, ReadvSyscall, + readv(fd: c_int, iov: *const iovec, iovcnt: c_int) -> ssize_t +); + +impl_io_uring!(IoUringReadvSyscall, ReadvSyscall, + readv(fd: c_int, iov: *const iovec, iovcnt: c_int) -> ssize_t +); + +impl_nio_read_iovec!(NioReadvSyscall, ReadvSyscall, + readv(fd: c_int, iov: *const iovec, iovcnt: c_int,) -> ssize_t +); + +impl_raw!(RawReadvSyscall, ReadvSyscall, + readv(fd: c_int, iov: *const iovec, iovcnt: c_int) -> ssize_t +); diff --git a/open-coroutine-core/src/syscall/unix/recv.rs b/open-coroutine-core/src/syscall/unix/recv.rs index f0cd1931..5ae5fe77 100644 --- a/open-coroutine-core/src/syscall/unix/recv.rs +++ b/open-coroutine-core/src/syscall/unix/recv.rs @@ -42,7 +42,7 @@ impl_io_uring!(IoUringRecvSyscall, RecvSyscall, recv(fd: c_int, buf: *mut c_void, len: size_t, flags: c_int) -> ssize_t ); -impl_nio_expected_read!(NioRecvSyscall, RecvSyscall, +impl_nio_read_buf!(NioRecvSyscall, RecvSyscall, recv(fd: c_int, buf: *mut c_void, len: size_t, flags: c_int) -> ssize_t ); diff --git a/open-coroutine-core/src/syscall/unix/send.rs b/open-coroutine-core/src/syscall/unix/send.rs index 9479b820..941bc0b4 100644 --- a/open-coroutine-core/src/syscall/unix/send.rs +++ b/open-coroutine-core/src/syscall/unix/send.rs @@ -42,7 +42,7 @@ impl_io_uring!(IoUringSendSyscall, SendSyscall, send(fd: c_int, buf: *const c_void, len: size_t, flags: c_int) -> ssize_t ); -impl_nio_expected_write!(NioSendSyscall, SendSyscall, +impl_nio_write_buf!(NioSendSyscall, SendSyscall, send(fd: c_int, buf: *const c_void, len: size_t, flags: c_int) -> ssize_t ); diff --git a/open-coroutine-core/src/syscall/unix/writev.rs b/open-coroutine-core/src/syscall/unix/writev.rs new file mode 100644 index 00000000..c0e52627 --- /dev/null +++ b/open-coroutine-core/src/syscall/unix/writev.rs @@ -0,0 +1,49 @@ +use libc::{iovec, ssize_t}; +use once_cell::sync::Lazy; +use std::ffi::c_int; + +#[must_use] +pub extern "C" fn writev( + fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int) -> ssize_t>, + fd: c_int, + iov: *const iovec, + iovcnt: c_int, +) -> ssize_t { + cfg_if::cfg_if! { + if #[cfg(all(target_os = "linux", feature = "io_uring"))] { + static CHAIN: Lazy< + WritevSyscallFacade>> + > = Lazy::new(Default::default); + } else { + static CHAIN: Lazy>> = + Lazy::new(Default::default); + } + } + CHAIN.writev(fn_ptr, fd, iov, iovcnt) +} + +trait WritevSyscall { + extern "C" fn writev( + &self, + fn_ptr: Option<&extern "C" fn(c_int, *const iovec, c_int) -> ssize_t>, + fd: c_int, + iov: *const iovec, + iovcnt: c_int, + ) -> ssize_t; +} + +impl_facade!(WritevSyscallFacade, WritevSyscall, + writev(fd: c_int, iov: *const iovec, iovcnt: c_int) -> ssize_t +); + +impl_io_uring!(IoUringWritevSyscall, WritevSyscall, + writev(fd: c_int, iov: *const iovec, iovcnt: c_int) -> ssize_t +); + +impl_nio_write_iovec!(NioWritevSyscall, WritevSyscall, + writev(fd: c_int, iov: *const iovec, iovcnt: c_int,) -> ssize_t +); + +impl_raw!(RawWritevSyscall, WritevSyscall, + writev(fd: c_int, iov: *const iovec, iovcnt: c_int) -> ssize_t +);