open-coroutine-core 0.7.0

The open-coroutine is a simple, efficient and generic coroutine library.
Documentation
use std::ffi::{c_int, c_void};
use libc::{socklen_t, timeval};
use crate::syscall::get_time_limit;
use crate::syscall::unix::{RECV_TIME_LIMIT, SEND_TIME_LIMIT};

trait SetsockoptSyscall {
    extern "C" fn setsockopt(
        &self,
        fn_ptr: Option<&extern "C" fn(c_int, c_int, c_int, *const c_void, socklen_t) -> c_int>,
        socket: c_int,
        level: c_int,
        name: c_int,
        value: *const c_void,
        option_len: socklen_t
    ) -> c_int;
}

impl_syscall!(SetsockoptSyscallFacade, NioSetsockoptSyscall, RawSetsockoptSyscall,
    setsockopt(socket: c_int, level: c_int, name: c_int, value: *const c_void, option_len: socklen_t) -> c_int
);

impl_facade!(SetsockoptSyscallFacade, SetsockoptSyscall,
    setsockopt(socket: c_int, level: c_int, name: c_int, value: *const c_void, option_len: socklen_t) -> c_int
);

#[repr(C)]
#[derive(Debug, Default)]
struct NioSetsockoptSyscall<I: SetsockoptSyscall> {
    inner: I,
}

impl<I: SetsockoptSyscall> SetsockoptSyscall for NioSetsockoptSyscall<I> {
    extern "C" fn setsockopt(
        &self,
        fn_ptr: Option<&extern "C" fn(c_int, c_int, c_int, *const c_void, socklen_t) -> c_int>,
        socket: c_int,
        level: c_int,
        name: c_int,
        value: *const c_void,
        option_len: socklen_t
    ) -> c_int {
        let r= self.inner.setsockopt(fn_ptr, socket, level, name, value, option_len);
        if 0 == r && libc::SOL_SOCKET == level {
            if libc::SO_SNDTIMEO == name {
                assert!(SEND_TIME_LIMIT.insert(socket, get_time_limit(unsafe { &*value.cast::<timeval>() })).is_none());
            } else if libc::SO_RCVTIMEO == name {
                assert!(RECV_TIME_LIMIT.insert(socket, get_time_limit(unsafe { &*value.cast::<timeval>() })).is_none());
            }
        }
        r
    }
}

impl_raw!(RawSetsockoptSyscall, SetsockoptSyscall,
    setsockopt(socket: c_int, level: c_int, name: c_int, value: *const c_void, option_len: socklen_t) -> c_int
);