alef 0.83.3

Opinionated polyglot binding generator for Rust libraries
Documentation
/// Run owned Rust work while the calling Ruby thread releases the GVL.
fn alef_magnus_run_without_gvl<F, T>(callback: F) -> T
where
    F: FnOnce() -> T,
{
    struct RunState<F, T> {
        callback: Option<F>,
        result: Option<std::thread::Result<T>>,
    }

    extern "C" fn run_without_gvl<F, T>(data: *mut std::ffi::c_void) -> *mut std::ffi::c_void
    where
        F: FnOnce() -> T,
    {
        // SAFETY: `data` points to the caller's RunState for the duration of this callback.
        let state = unsafe { &mut *(data as *mut RunState<F, T>) };
        let Some(callback) = state.callback.take() else {
            state.result = Some(Err(Box::new("Alef Magnus callback already consumed")));
            return std::ptr::null_mut();
        };
        state.result = Some(std::panic::catch_unwind(std::panic::AssertUnwindSafe(callback)));
        std::ptr::null_mut()
    }

    extern "C" fn unblock_run(_data: *mut std::ffi::c_void) {}

    let mut state = RunState {
        callback: Some(callback),
        result: None,
    };
    // SAFETY: Ruby invokes the callback synchronously, and `state` remains live until it returns.
    unsafe {
        rb_sys::rb_thread_call_without_gvl(
            Some(run_without_gvl::<F, T>),
            &mut state as *mut RunState<F, T> as *mut std::ffi::c_void,
            Some(unblock_run),
            std::ptr::null_mut(),
        );
    }

    match state.result.expect("Alef Magnus callback did not run") {
        Ok(result) => result,
        Err(payload) => std::panic::resume_unwind(payload),
    }
}