]> git.proxmox.com Git - rustc.git/blame - vendor/lock_api/src/lib.rs
New upstream version 1.54.0+dfsg1
[rustc.git] / vendor / lock_api / src / lib.rs
CommitLineData
b7449926
XL
1// Copyright 2018 Amanieu d'Antras
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8//! This library provides type-safe and fully-featured `Mutex` and `RwLock`
9//! types which wrap a simple raw mutex or rwlock type. This has several
10//! benefits: not only does it eliminate a large portion of the work in
11//! implementing custom lock types, it also allows users to write code which is
12//! generic with regards to different lock implementations.
13//!
e1599b0c 14//! Basic usage of this crate is very straightforward:
b7449926
XL
15//!
16//! 1. Create a raw lock type. This should only contain the lock state, not any
17//! data protected by the lock.
18//! 2. Implement the `RawMutex` trait for your custom lock type.
19//! 3. Export your mutex as a type alias for `lock_api::Mutex`, and
20//! your mutex guard as a type alias for `lock_api::MutexGuard`.
21//! See the [example](#example) below for details.
22//!
23//! This process is similar for RwLocks, except that two guards need to be
24//! exported instead of one. (Or 3 guards if your type supports upgradable read
25//! locks, see [extension traits](#extension-traits) below for details)
26//!
27//! # Example
28//!
29//! ```
e1599b0c
XL
30//! use lock_api::{RawMutex, Mutex, GuardSend};
31//! use std::sync::atomic::{AtomicBool, Ordering};
b7449926
XL
32//!
33//! // 1. Define our raw lock type
34//! pub struct RawSpinlock(AtomicBool);
35//!
36//! // 2. Implement RawMutex for this type
37//! unsafe impl RawMutex for RawSpinlock {
e1599b0c
XL
38//! const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false));
39//!
40//! // A spinlock guard can be sent to another thread and unlocked there
41//! type GuardMarker = GuardSend;
b7449926
XL
42//!
43//! fn lock(&self) {
44//! // Note: This isn't the best way of implementing a spinlock, but it
45//! // suffices for the sake of this example.
46//! while !self.try_lock() {}
47//! }
48//!
49//! fn try_lock(&self) -> bool {
ba9703b0
XL
50//! self.0
51//! .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
52//! .is_ok()
b7449926
XL
53//! }
54//!
f035d41b 55//! unsafe fn unlock(&self) {
b7449926
XL
56//! self.0.store(false, Ordering::Release);
57//! }
58//! }
59//!
60//! // 3. Export the wrappers. This are the types that your users will actually use.
61//! pub type Spinlock<T> = lock_api::Mutex<RawSpinlock, T>;
62//! pub type SpinlockGuard<'a, T> = lock_api::MutexGuard<'a, RawSpinlock, T>;
63//! ```
64//!
65//! # Extension traits
66//!
67//! In addition to basic locking & unlocking functionality, you have the option
68//! of exposing additional functionality in your lock types by implementing
69//! additional traits for it. Examples of extension features include:
70//!
71//! - Fair unlocking (`RawMutexFair`, `RawRwLockFair`)
72//! - Lock timeouts (`RawMutexTimed`, `RawRwLockTimed`)
73//! - Downgradable write locks (`RawRwLockDowngradable`)
74//! - Recursive read locks (`RawRwLockRecursive`)
75//! - Upgradable read locks (`RawRwLockUpgrade`)
76//!
77//! The `Mutex` and `RwLock` wrappers will automatically expose this additional
78//! functionality if the raw lock type implements these extension traits.
79//!
80//! # Cargo features
81//!
82//! This crate supports two cargo features:
83//!
84//! - `owning_ref`: Allows your lock types to be used with the `owning_ref` crate.
85//! - `nightly`: Enables nightly-only features. At the moment the only such
86//! feature is `const fn` constructors for lock types.
87
88#![no_std]
89#![warn(missing_docs)]
e1599b0c 90#![warn(rust_2018_idioms)]
17df50a5 91#![cfg_attr(feature = "nightly", feature(const_fn_trait_bound))]
b7449926
XL
92
93#[macro_use]
94extern crate scopeguard;
95
b7449926
XL
96/// Marker type which indicates that the Guard type for a lock is `Send`.
97pub struct GuardSend(());
98
99/// Marker type which indicates that the Guard type for a lock is not `Send`.
100pub struct GuardNoSend(*mut ());
101
5869c6ff
XL
102unsafe impl Sync for GuardNoSend {}
103
b7449926 104mod mutex;
e1599b0c 105pub use crate::mutex::*;
b7449926
XL
106
107mod remutex;
e1599b0c 108pub use crate::remutex::*;
b7449926
XL
109
110mod rwlock;
e1599b0c 111pub use crate::rwlock::*;