]> git.proxmox.com Git - rustc.git/blob - vendor/lock_api-0.3.4/src/lib.rs
New upstream version 1.48.0+dfsg1
[rustc.git] / vendor / lock_api-0.3.4 / src / lib.rs
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 //!
14 //! Basic usage of this crate is very straightforward:
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 //! ```
30 //! use lock_api::{RawMutex, Mutex, GuardSend};
31 //! use std::sync::atomic::{AtomicBool, Ordering};
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 {
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;
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 {
50 //! self.0
51 //! .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
52 //! .is_ok()
53 //! }
54 //!
55 //! fn unlock(&self) {
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)]
90 #![warn(rust_2018_idioms)]
91 #![cfg_attr(feature = "nightly", feature(const_fn))]
92
93 #[macro_use]
94 extern crate scopeguard;
95
96 /// Marker type which indicates that the Guard type for a lock is `Send`.
97 pub struct GuardSend(());
98
99 /// Marker type which indicates that the Guard type for a lock is not `Send`.
100 pub struct GuardNoSend(*mut ());
101
102 mod mutex;
103 pub use crate::mutex::*;
104
105 mod remutex;
106 pub use crate::remutex::*;
107
108 mod rwlock;
109 pub use crate::rwlock::*;