1 unstable release
Uses old Rust 2015
| 0.1.0 | Apr 28, 2018 |
|---|
#1090 in Concurrency
50KB
650 lines
Flexible Locks
This crate aims at providing generic, flexible implementations of locking
primitives. For now, it only provides Mutex types (i.e. no RwLock, etc.),
without poisoning, and without try_lock. Support for those can be
added in the future if there is interest (patches welcome). Poisoning is not
necessary with panic=abort.
The provided types allow flexibility in layout and locking implementation.
Differences from std::sync::Mutex
- No poisoning.
- No
try_lock. - The underlying raw mutex primitive can be of any kind, within a
Boxor not, as long as theRawMutextrait is implemented. Choose carefully. - The raw mutex primitive can be embedded anywhere in the data type. See the
MutexWraptype for a variant that looks more likestd::sync::Mutex, but still allows to use a specific raw mutex primitive. - With care, this can allow to share data through FFI and contend on the same
locks. See the
ffi-exampledirectory.
Examples
extern crate flexible_locks;
#[macro_use]
extern crate flexible_locks_derive;
use flexible_locks::{Mutex, RawMutex};
// Pick your choice of raw mutex;
#[cfg(windows)]
use flexible_locks::SRWLOCK as RawOsMutex;
#[cfg(unix)]
use flexible_locks::pthread_mutex_t as RawOsMutex;
use std::sync::Arc;
use std::thread;
use std::sync::mpsc::channel;
#[derive(MutexProtected, Default)]
struct Data {
a: usize,
b: usize,
#[mutex]
mutex: RawOsMutex,
}
const N: usize = 10;
fn main() {
// Spawn a few threads to increment a shared variable (non-atomically),
// and let the main thread know once all increments are done.
//
// Here we're using an Arc to share memory among threads, and the data
// inside the Arc is protected with a mutex.
let data = Arc::new(Mutex::new(Data::default()));
let (tx, rx) = channel();
for _ in 0..N {
let (data, tx) = (data.clone(), tx.clone());
thread::spawn(move || {
// The shared state can only be accessed once the lock is held.
// Our non-atomic increment is safe because we're the only thread
// which can access the shared state when the lock is held.
let mut data = data.lock();
data.a += 1;
if data.a == N {
tx.send(()).unwrap();
}
// the lock is unlocked here when `data` goes out of scope.
});
}
rx.recv().unwrap();
}
Features
The parking_lot feature can be enabled, providing a RawMutex
implementation for parking_log::Mutex<()>.
License: Apache-2.0/MIT
Dependencies
~2.5MB
~54K SLoC