use std::sync::Arc;
use block2::{Block, RcBlock};
use parking_lot::Mutex;
use super::{VmnetReturn, xpc::XpcObject};
#[derive(Debug)]
pub struct StartCallbackOutcome {
pub status: VmnetReturn,
pub param: Option<XpcObject>,
}
#[derive(Debug)]
pub struct StartContext {
pub semaphore: super::dispatch::Semaphore,
pub outcome: Mutex<Option<StartCallbackOutcome>>,
}
impl StartContext {
pub fn new(semaphore: super::dispatch::Semaphore) -> Arc<Self> {
Arc::new(Self {
semaphore,
outcome: Mutex::new(None),
})
}
}
pub fn start_block(
ctx: Arc<StartContext>,
) -> RcBlock<dyn Fn(u32, *mut std::os::raw::c_void) + 'static> {
RcBlock::new(move |status: u32, param: *mut std::os::raw::c_void| {
let outcome = StartCallbackOutcome {
status: VmnetReturn::from_raw(status),
param: unsafe { XpcObject::from_raw_retained_or_null(param) },
};
*ctx.outcome.lock() = Some(outcome);
ctx.semaphore.signal();
})
}
pub fn stop_block(ctx: Arc<StartContext>) -> RcBlock<dyn Fn(u32) + 'static> {
RcBlock::new(move |status: u32| {
let outcome = StartCallbackOutcome {
status: VmnetReturn::from_raw(status),
param: None,
};
*ctx.outcome.lock() = Some(outcome);
ctx.semaphore.signal();
})
}
#[must_use]
pub fn as_raw_start(
b: &RcBlock<dyn Fn(u32, *mut std::os::raw::c_void) + 'static>,
) -> *const Block<dyn Fn(u32, *mut std::os::raw::c_void) + 'static> {
&raw const **b
}
#[must_use]
pub fn as_raw_stop(b: &RcBlock<dyn Fn(u32) + 'static>) -> *const Block<dyn Fn(u32) + 'static> {
&raw const **b
}