]>
git.proxmox.com Git - rustc.git/blob - vendor/lock_api-0.3.4/src/lib.rs
1 // Copyright 2018 Amanieu d'Antras
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.
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.
14 //! Basic usage of this crate is very straightforward:
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.
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)
30 //! use lock_api::{RawMutex, Mutex, GuardSend};
31 //! use std::sync::atomic::{AtomicBool, Ordering};
33 //! // 1. Define our raw lock type
34 //! pub struct RawSpinlock(AtomicBool);
36 //! // 2. Implement RawMutex for this type
37 //! unsafe impl RawMutex for RawSpinlock {
38 //! const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false));
40 //! // A spinlock guard can be sent to another thread and unlocked there
41 //! type GuardMarker = GuardSend;
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() {}
49 //! fn try_lock(&self) -> bool {
51 //! .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
55 //! fn unlock(&self) {
56 //! self.0.store(false, Ordering::Release);
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>;
65 //! # Extension traits
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:
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`)
77 //! The `Mutex` and `RwLock` wrappers will automatically expose this additional
78 //! functionality if the raw lock type implements these extension traits.
82 //! This crate supports two cargo features:
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.
89 #![warn(missing_docs)]
90 #![warn(rust_2018_idioms)]
91 #![cfg_attr(feature = "nightly", feature(const_fn))]
94 extern crate scopeguard
;
96 /// Marker type which indicates that the Guard type for a lock is `Send`.
97 pub struct GuardSend(());
99 /// Marker type which indicates that the Guard type for a lock is not `Send`.
100 pub struct GuardNoSend(*mut ());
103 pub use crate::mutex
::*;
106 pub use crate::remutex
::*;
109 pub use crate::rwlock
::*;