emf_core_base_rs_ffi/sys/sync_handler.rs
1//! Interface of a sync handler
2//!
3//! Any object that can be wrapped into a [SyncHandlerInterface] can be used as a sync handler.
4use crate::{Bool, TypeWrapper};
5use std::ptr::NonNull;
6
7/// Opaque structure representing a sync handler.
8#[repr(C)]
9pub struct SyncHandler {
10 _dummy: [u8; 0],
11}
12
13pub type LockFn = TypeWrapper<unsafe extern "C-unwind" fn(handler: Option<NonNull<SyncHandler>>)>;
14pub type TryLockFn =
15 TypeWrapper<unsafe extern "C-unwind" fn(handler: Option<NonNull<SyncHandler>>) -> Bool>;
16pub type UnlockFn = TypeWrapper<unsafe extern "C-unwind" fn(handler: Option<NonNull<SyncHandler>>)>;
17
18/// Interface of a sync handler.
19#[repr(C)]
20#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
21pub struct SyncHandlerInterface {
22 pub handler: Option<NonNull<SyncHandler>>,
23 pub lock_fn: LockFn,
24 pub try_lock_fn: TryLockFn,
25 pub unlock_fn: UnlockFn,
26}
27
28unsafe impl Send for SyncHandlerInterface {}
29unsafe impl Sync for SyncHandlerInterface {}
30
31/// Helper trait for using a sync handler.
32pub trait SyncHandlerBinding {
33 /// Locks the synchronisation handler.
34 ///
35 /// The calling thread is stalled until the lock can be acquired.
36 /// Only one thread can hold the lock at a time.
37 ///
38 /// # Safety
39 ///
40 /// The function crosses the ffi boundary.
41 /// Direct usage of a [SyncHandlerBinding] may break some invariants
42 /// of the sys api, if not handled with care.
43 unsafe fn lock(&self);
44
45 /// Tries to lock the synchronisation handler.
46 ///
47 /// The function fails if another thread already holds the lock.
48 ///
49 /// # Return
50 ///
51 /// [Bool::True] on success and [Bool::False] otherwise.
52 ///
53 /// # Safety
54 ///
55 /// The function crosses the ffi boundary.
56 /// Direct usage of a [SyncHandlerBinding] may break some invariants
57 /// of the sys api, if not handled with care.
58 unsafe fn try_lock(&self) -> Bool;
59
60 /// Unlocks the synchronisation handler.
61 ///
62 /// # Safety
63 ///
64 /// The function crosses the ffi boundary.
65 /// Trying to call this function without prior locking is undefined behaviour.
66 /// Direct usage of a [SyncHandlerBinding] may break some invariants
67 /// of the sys api, if not handled with care.
68 unsafe fn unlock(&self);
69}
70
71impl SyncHandlerBinding for SyncHandlerInterface {
72 #[inline]
73 unsafe fn lock(&self) {
74 (self.lock_fn)(self.handler)
75 }
76
77 #[inline]
78 unsafe fn try_lock(&self) -> Bool {
79 (self.try_lock_fn)(self.handler)
80 }
81
82 #[inline]
83 unsafe fn unlock(&self) {
84 (self.unlock_fn)(self.handler)
85 }
86}