1 // Copyright 2023 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //! An abstraction layer for Rust synchronization primitives which provides both no_std and std library 16 //! based implementations 17 18 #![no_std] 19 20 #[cfg(feature = "std")] 21 extern crate std; 22 23 /// A Spinlock-based implementation of Mutex using the `spin` crate that can be used in `no_std` 24 /// environments. 25 /// 26 /// Available with the feature `spin`. 27 #[cfg(feature = "spin")] 28 pub mod spin; 29 30 /// A `std` implementation that yields to the operating system while waiting for the lock. 31 /// 32 /// Available with the feature `std`. 33 #[cfg(feature = "std")] 34 pub mod stdlib; 35 36 /// A trait for mutex implementations that doesn't support poisoning. If the thread panicked while 37 /// holding the mutex, the data will be released normally (as spin::Mutex would). 38 pub trait NoPoisonMutex<T> { 39 /// An RAII guard for the mutex value that is returned when the lock is successfully obtained. 40 type MutexGuard<'a> 41 where 42 Self: 'a; 43 44 /// Acquires a mutex, blocking the current thread until it is able to do so. 45 /// 46 /// This function will block the local thread until it is available to acquire the mutex. Upon 47 /// returning, the thread is the only thread with the lock held. An RAII guard is returned to 48 /// allow scoped unlock of the lock. When the guard goes out of scope, the mutex will be 49 /// unlocked. 50 /// 51 /// The exact behavior on locking a mutex in the thread which already holds the lock is left 52 /// unspecified. However, this function will not return on the second call (it might panic or 53 /// deadlock, for example). lock(&self) -> Self::MutexGuard<'_>54 fn lock(&self) -> Self::MutexGuard<'_>; 55 56 /// Attempts to acquire this lock. 57 /// 58 /// If the lock could not be acquired at this time, then `None` is returned. Otherwise, an RAII 59 /// `MutexGuard` is returned. The lock will be unlocked when the guard is dropped. 60 /// 61 /// This function does not block. try_lock(&self) -> Option<Self::MutexGuard<'_>>62 fn try_lock(&self) -> Option<Self::MutexGuard<'_>>; 63 64 /// Creates a new mutex in an unlocked state ready for use. new(value: T) -> Self65 fn new(value: T) -> Self; 66 } 67 68 /// A reader-writer lock. This type of lock allows a number of readers or at most one writer at 69 /// any point in time. 70 pub trait RwLock<T> { 71 /// RAII structure used to release the shared read access of a lock when dropped. 72 type RwLockReadGuard<'a> 73 where 74 Self: 'a; 75 76 /// RAII structure used to release the exclusive write access of a lock when dropped. 77 type RwLockWriteGuard<'a> 78 where 79 Self: 'a; 80 81 /// Locks this RwLock with shared read access, blocking the current thread until it can be acquired. read(&self) -> Self::RwLockReadGuard<'_>82 fn read(&self) -> Self::RwLockReadGuard<'_>; 83 84 /// Locks this RwLock with exclusive write access, blocking the current thread until it can be acquired. write(&self) -> Self::RwLockWriteGuard<'_>85 fn write(&self) -> Self::RwLockWriteGuard<'_>; 86 } 87