91 lines
2.6 KiB
Rust
91 lines
2.6 KiB
Rust
//! # Binary extension definition
|
|
//!
|
|
//! A binary extension is a DLL / shared object / dylib with a symbol called
|
|
//! `orchid_extension_main` which accepts a single argument of type
|
|
//! [ExtensionContext]. Once that is received, communication continuees through
|
|
//! the channel with the same protocol outlined in [crate::proto]
|
|
|
|
use unsync_pipe::{Reader, Writer};
|
|
|
|
/// !Send !Sync owned waker
|
|
///
|
|
/// This object is [Clone] for convenience but it has `drop` and no `clone` so
|
|
/// interactions must reflect a single logical owner
|
|
#[derive(Clone, Copy)]
|
|
#[repr(C)]
|
|
pub struct OwnedWakerBin {
|
|
pub data: *const (),
|
|
/// `self`
|
|
pub drop: extern "C" fn(*const ()),
|
|
/// `self`
|
|
pub wake: extern "C" fn(*const ()),
|
|
/// `&self`
|
|
pub wake_ref: extern "C" fn(*const ()),
|
|
}
|
|
|
|
/// !Send !Sync, equivalent to `&mut Context<'a>`, hence no `drop`.
|
|
/// When received in [FutureBin::poll], it must not outlive the call.
|
|
///
|
|
/// You cannot directly wake using this waker, because such a trampoline would
|
|
/// pass through the binary interface twice for no reason. An efficient
|
|
/// implementation should implement that trampoline action internally, whereas
|
|
/// an inefficient but compliant implementation can clone a fresh waker and use
|
|
/// it up.
|
|
#[derive(Clone, Copy)]
|
|
#[repr(C)]
|
|
pub struct FutureContextBin {
|
|
pub data: *const (),
|
|
/// `&self`
|
|
pub waker: extern "C" fn(*const ()) -> OwnedWakerBin,
|
|
}
|
|
|
|
/// ABI-stable `Poll<()>`
|
|
#[derive(Clone, Copy)]
|
|
#[repr(C)]
|
|
pub enum UnitPoll {
|
|
Pending,
|
|
Ready,
|
|
}
|
|
|
|
/// ABI-stable `Pin<Box<dyn Future<Output = ()>>>`
|
|
///
|
|
/// This object is [Clone] for convenience, but it has `drop` and no `clone` so
|
|
/// interactions must reflect a single logical owner
|
|
#[derive(Clone, Copy)]
|
|
#[repr(C)]
|
|
pub struct FutureBin {
|
|
pub data: *const (),
|
|
/// `self`
|
|
pub drop: extern "C" fn(*const ()),
|
|
/// `&mut self` Equivalent to [Future::poll]
|
|
pub poll: extern "C" fn(*const (), FutureContextBin) -> UnitPoll,
|
|
}
|
|
|
|
/// Handle for a runtime that allows its holder to spawn futures across dynamic
|
|
/// library boundaries
|
|
#[derive(Clone, Copy)]
|
|
#[repr(C)]
|
|
pub struct SpawnerBin {
|
|
pub data: *const (),
|
|
/// `self`
|
|
pub drop: extern "C" fn(*const ()),
|
|
/// `&self` Add a future to this extension's task
|
|
pub spawn: extern "C" fn(*const (), FutureBin),
|
|
}
|
|
|
|
/// Extension context.
|
|
///
|
|
/// This struct is a plain old value, all of the contained values have a
|
|
/// distinct `drop` member
|
|
#[repr(C)]
|
|
pub struct ExtensionContext {
|
|
/// Spawns tasks associated with this extension
|
|
pub spawner: SpawnerBin,
|
|
/// serialized [crate::HostExtChannel]
|
|
pub input: Reader,
|
|
/// serialized [crate::ExtHostChannel]
|
|
pub output: Writer,
|
|
/// UTF-8 log stream directly to log service.
|
|
pub log: Writer,
|
|
}
|