starnix_lifecycle/
delayed_releaser.rs1use starnix_types::ownership::ReleaseGuard;
6use std::marker::PhantomData;
7use std::mem::ManuallyDrop;
8use std::ops::Deref;
9
10pub trait ReleaserAction<T> {
11 fn release(t: ReleaseGuard<T>);
12}
13
14pub struct ObjectReleaser<T, F: ReleaserAction<T>>(ManuallyDrop<ReleaseGuard<T>>, PhantomData<F>);
17
18impl<T: Default, F: ReleaserAction<T>> Default for ObjectReleaser<T, F> {
19 fn default() -> Self {
20 Self::from(T::default())
21 }
22}
23
24impl<T, F: ReleaserAction<T>> From<T> for ObjectReleaser<T, F> {
25 fn from(object: T) -> Self {
26 Self(ManuallyDrop::new(object.into()), Default::default())
27 }
28}
29
30impl<T, F: ReleaserAction<T>> Drop for ObjectReleaser<T, F> {
31 fn drop(&mut self) {
32 #[allow(
36 clippy::undocumented_unsafe_blocks,
37 reason = "Force documented unsafe blocks in Starnix"
38 )]
39 let object = unsafe { ManuallyDrop::take(&mut self.0) };
40 F::release(object);
41 }
42}
43
44impl<T: std::fmt::Debug, F: ReleaserAction<T>> std::fmt::Debug for ObjectReleaser<T, F> {
45 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46 self.deref().fmt(f)
47 }
48}
49
50impl<T, F: ReleaserAction<T>> std::ops::Deref for ObjectReleaser<T, F> {
51 type Target = T;
52
53 fn deref(&self) -> &Self::Target {
54 self.0.deref()
55 }
56}
57
58impl<T, F: ReleaserAction<T>> std::borrow::Borrow<T> for ObjectReleaser<T, F> {
59 fn borrow(&self) -> &T {
60 self.deref()
61 }
62}
63
64impl<T, F: ReleaserAction<T>> std::convert::AsRef<T> for ObjectReleaser<T, F> {
65 fn as_ref(&self) -> &T {
66 self.deref()
67 }
68}