1
#![allow(dead_code)]
2

            
3
use core::{
4
    mem::ManuallyDrop,
5
    ops::{Deref, DerefMut},
6
};
7

            
8
use portable_atomic::{AtomicPtr, Ordering};
9

            
10
/// An optional `extern "C" fn()` stored as an atomic pointer.
11
pub(crate) struct CFnPtr(AtomicPtr<()>);
12

            
13
impl CFnPtr {
14
    pub const fn new() -> Self {
15
        Self(AtomicPtr::new(core::ptr::null_mut()))
16
    }
17

            
18
    pub fn store(&self, f: extern "C" fn()) {
19
        self.0.store(f as *mut (), Ordering::Relaxed);
20
    }
21

            
22
    pub fn clear(&self) {
23
        self.0.store(core::ptr::null_mut(), Ordering::Relaxed);
24
    }
25

            
26
    pub fn call(&self) -> bool {
27
        let ptr = self.0.load(Ordering::Relaxed);
28
20
        if !ptr.is_null() {
29
20
            unsafe { (core::mem::transmute::<*mut (), extern "C" fn()>(ptr))() };
30
            true
31
        } else {
32
            false
33
        }
34
    }
35
}
36

            
37
pub trait Sealed {}
38

            
39
#[non_exhaustive]
40
#[doc(hidden)]
41
/// Magical incantation to gain access to internal APIs.
42
pub struct Internal;
43

            
44
impl Internal {
45
    /// Obtains magical powers to access internal APIs.
46
    ///
47
    /// # Safety
48
    ///
49
    /// Calling this method accepts that this is an internal
50
    /// API that is not guaranteed to be documented, stable, or working,
51
    /// and may change at any time.
52
    ///
53
    /// Calling this method also declares that other solutions have been tried, and that
54
    /// a feature request or an issue has been opened to discuss the
55
    /// need for this function.
56
    pub unsafe fn conjure() -> Self {
57
        Self
58
    }
59
}
60

            
61
pub(crate) struct DropGuard<I, F: FnOnce(I)> {
62
    inner: ManuallyDrop<I>,
63
    on_drop: ManuallyDrop<F>,
64
}
65

            
66
impl<I, F: FnOnce(I)> DropGuard<I, F> {
67
    pub(crate) fn new(inner: I, on_drop: F) -> Self {
68
        Self {
69
            inner: ManuallyDrop::new(inner),
70
            on_drop: ManuallyDrop::new(on_drop),
71
        }
72
    }
73

            
74
    pub(crate) fn defuse(self) {
75
        core::mem::forget(self);
76
    }
77
}
78

            
79
impl<I, F: FnOnce(I)> Drop for DropGuard<I, F> {
80
    fn drop(&mut self) {
81
        let inner = unsafe { ManuallyDrop::take(&mut self.inner) };
82
        let on_drop = unsafe { ManuallyDrop::take(&mut self.on_drop) };
83
        (on_drop)(inner)
84
    }
85
}
86

            
87
impl<I, F: FnOnce(I)> Deref for DropGuard<I, F> {
88
    type Target = I;
89

            
90
    fn deref(&self) -> &I {
91
        &self.inner
92
    }
93
}
94

            
95
impl<I, F: FnOnce(I)> DerefMut for DropGuard<I, F> {
96
    fn deref_mut(&mut self) -> &mut I {
97
        &mut self.inner
98
    }
99
}