open-coroutine-core 0.7.0

The open-coroutine is a simple, efficient and generic coroutine library.
Documentation
use crate::net::EventLoops;
use crate::scheduler::SchedulableCoroutine;
use libc::pthread_mutex_t;
use std::ffi::c_int;

trait PthreadMutexLockSyscall {
    extern "C" fn pthread_mutex_lock(
        &self,
        fn_ptr: Option<&extern "C" fn(*mut pthread_mutex_t) -> c_int>,
        lock: *mut pthread_mutex_t,
    ) -> c_int;
}

impl_syscall!(PthreadMutexLockSyscallFacade, NioPthreadMutexLockSyscall, RawPthreadMutexLockSyscall,
    pthread_mutex_lock(lock: *mut pthread_mutex_t) -> c_int
);

impl_facade!(PthreadMutexLockSyscallFacade, PthreadMutexLockSyscall,
    pthread_mutex_lock(lock: *mut pthread_mutex_t) -> c_int
);

#[repr(C)]
#[derive(Debug, Copy, Clone, Default)]
struct NioPthreadMutexLockSyscall<I: PthreadMutexLockSyscall> {
    inner: I,
}

impl<I: PthreadMutexLockSyscall> PthreadMutexLockSyscall for NioPthreadMutexLockSyscall<I> {
    extern "C" fn pthread_mutex_lock(
        &self,
        fn_ptr: Option<&extern "C" fn(*mut pthread_mutex_t) -> c_int>,
        lock: *mut pthread_mutex_t,
    ) -> c_int {
        if SchedulableCoroutine::current().is_none() {
            return self.inner.pthread_mutex_lock(fn_ptr, lock);
        }
        loop {
            let r = unsafe { libc::pthread_mutex_trylock(lock) };
            if 0 == r
                || r != libc::EBUSY
                || EventLoops::wait_event(Some(crate::common::constants::SLICE)).is_err()
            {
                return r;
            }
        }
    }
}

impl_raw!(RawPthreadMutexLockSyscall, PthreadMutexLockSyscall,
    pthread_mutex_lock(lock: *mut pthread_mutex_t) -> c_int
);