1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//! This crate defines a locking structure wrapping an `Option` value. The lock
//! can be acquired using a single atomic operation. The `OptionLock` structure
//! is represented as one atomic `u8` variable along with the current value of
//! the lock (which may be empty). It can be constructed in `const` contexts.
//!
//! The `try_lock` and `try_take` operations are non-blocking and appropriate
//! for using within a polled `Future`, but the lock cannot register wakers or
//! automatically park the current thread. A traditional `Mutex` or the
//! `async-lock` crate may be used in this case.
//!
//! This structure allows for multiple usage patterns. A basic example (in this
//! case an AtomicI32 could be substituted):
//!
//! ```
//! use option_lock::{OptionLock, OptionGuard};
//!
//! static SHARED: OptionLock<i32> = OptionLock::new(0);
//!
//! fn try_increase() -> bool {
//!   if let Ok(mut guard) = SHARED.try_lock() {
//!     let next = guard.take().unwrap() + 1;
//!     OptionGuard::replace(&mut guard, next);
//!     true
//!   } else {
//!     false
//!   }
//! }
//! ```
//!
//! There are additional examples in the code repository.
//!
//! This crate uses `unsafe` code blocks. It is `no_std`-compatible when compiled
//! without the `std` feature.

#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(missing_docs, missing_debug_implementations, rust_2018_idioms)]

#[cfg(any(test, feature = "alloc"))]
extern crate alloc;

mod error;
pub use self::error::OptionLockError;

mod lock;

pub use self::lock::{OptionGuard, OptionLock};

#[cfg(feature = "alloc")]
mod arc;
#[cfg(feature = "alloc")]
pub use self::arc::{MutexGuardArc, OptionGuardArc};

mod once;
pub use self::once::{Lazy, OnceCell};

mod mutex;
pub use self::mutex::{Mutex, MutexGuard};