process_owned/
lib.rs

1#![warn(missing_docs)]
2
3//! This crate provides the `ProcessOwned` type, a value
4//! that shares its lifetime with the process *unless* it
5//! can be optimally freed earlier than that.
6//! 
7//! Internally, `ProcessOwned` uses the `Rc` type to
8//! ensure that the value is only dropped when the last
9//! owner is dropped. The specific implementation is
10//! subject to change for performance reasons.
11
12use std::{
13    rc::Rc,
14    cell::RefCell,
15    ops::Deref,
16    alloc::{alloc, Layout}
17};
18
19/// A value that is owned by the process itself.
20/// 
21/// The lifetime of a value is tied to its owner. When the
22/// owner is dropped, the value is dropped as well. This
23/// object uses the `Rc` type internally to ensure that
24/// the value is only dropped when the last owner is dropped.
25/// The specific implementation is subject to change for
26/// performance reasons.
27/// 
28/// When a `ProcessOwned` is initialized as a global static
29/// variable with the `lazy_static` crate, it will never be
30/// dropped. This allows values to easily and clearly share
31/// the scope of the entire process.
32#[derive(Clone, Debug)]
33pub struct ProcessOwned<T> {
34    value: Rc<T>
35}
36
37impl<T> ProcessOwned<T> {
38    /// Create a new `ProcessOwned` value.
39    /// 
40    /// # Examples
41    /// 
42    /// ```
43    /// use process_owned::ProcessOwned;
44    /// 
45    /// let value = ProcessOwned::new(5);
46    /// assert_eq!(*value, 5);
47    /// ```
48    pub fn new(value: T) -> Self {
49        ProcessOwned {
50            value: Rc::new(value)
51        }
52    }
53}
54
55impl<T> Deref for ProcessOwned<T> {
56    type Target = T;
57
58    fn deref(&self) -> &Self::Target {
59        &self.value
60    }
61}
62
63/// A mutable version of `ProcessOwned`.
64/// 
65/// This type is identical to `ProcessOwned` except that
66/// it provides mutability. This is done by using a
67/// `RefCell` internally.
68#[derive(Clone, Debug)]
69pub struct ProcessOwnedMut<T> {
70    value: Rc<RefCell<T>>
71}
72
73impl<T> ProcessOwnedMut<T> {
74    /// Create a new `ProcessOwnedMut` value.
75    /// 
76    /// # Examples
77    /// 
78    /// ```
79    /// use process_owned::ProcessOwnedMut;
80    /// 
81    /// let mut value = ProcessOwnedMut::new(5);
82    /// *value.borrow_mut() = 10;
83    /// assert_eq!(*value.borrow(), 10);
84    /// ```
85    pub fn new(value: T) -> Self {
86        ProcessOwnedMut {
87            value: Rc::new(RefCell::new(value))
88        }
89    }
90}
91
92impl<T> Deref for ProcessOwnedMut<T> {
93    type Target = RefCell<T>;
94
95    fn deref(&self) -> &Self::Target {
96        &self.value
97    }
98}
99
100/// A value that is truly owned by the process itself.
101/// 
102/// Using this type is similar to using a `ProcessOwned`
103/// with `lazy_static`, except the value can only be dropped
104/// when the process terminates. This can lead to memory
105/// leaks, but it can also be useful for values that are
106/// used throughout the entire process.
107#[derive(Clone, Debug)]
108pub struct Immortal<T> {
109    value: *const T
110}
111
112impl<T> Immortal<T> {
113    /// Creates a new `Immortal` value.
114    /// 
115    /// # Safety
116    /// 
117    /// This function is unsafe because it allocates memory
118    /// and stores a raw pointer to it. The memory is never
119    /// freed, so it is up to the caller to ensure that the
120    /// memory is not leaked.
121    /// 
122    /// # Examples
123    /// 
124    /// ```
125    /// use process_owned::Immortal;
126    /// 
127    /// unsafe {
128    ///     let immortal = Immortal::new(5);
129    ///     assert_eq!(*immortal, 5);
130    /// }
131    /// ```
132    pub unsafe fn new(value: T) -> Self {
133        let layout = Layout::new::<T>();
134        let ptr = alloc(layout) as *mut T;
135        *ptr = value;
136
137        Immortal {
138            value: ptr
139        }
140    }
141}
142
143impl<T> From<Immortal<T>> for *const T {
144    fn from(immortal: Immortal<T>) -> Self {
145        immortal.value
146    }
147}
148
149impl<T> Deref for Immortal<T> {
150    type Target = T;
151
152    fn deref(&self) -> &Self::Target {
153        unsafe { &*self.value }
154    }
155}