parent
cb4f82b2a9
commit
37d2497de3
@ -1,6 +1,6 @@
|
||||
mod mutex;
|
||||
mod condvar;
|
||||
//mod semaphore;
|
||||
mod semaphore;
|
||||
pub mod test;
|
||||
|
||||
pub use self::mutex::*;
|
||||
|
@ -1,2 +1,73 @@
|
||||
use super::mutex;
|
||||
//! A counting, blocking, semaphore.
|
||||
//!
|
||||
//! Borrowed from std at rust 1.7.0
|
||||
|
||||
use super::SpinNoIrqLock as Mutex;
|
||||
use super::Condvar;
|
||||
|
||||
/// A counting, blocking, semaphore.
|
||||
pub struct Semaphore {
|
||||
lock: Mutex<isize>,
|
||||
cvar: Condvar,
|
||||
}
|
||||
|
||||
/// An RAII guard which will release a resource acquired from a semaphore when
|
||||
/// dropped.
|
||||
pub struct SemaphoreGuard<'a> {
|
||||
sem: &'a Semaphore,
|
||||
}
|
||||
|
||||
impl Semaphore {
|
||||
/// Creates a new semaphore with the initial count specified.
|
||||
///
|
||||
/// The count specified can be thought of as a number of resources, and a
|
||||
/// call to `acquire` or `access` will block until at least one resource is
|
||||
/// available. It is valid to initialize a semaphore with a negative count.
|
||||
pub fn new(count: isize) -> Semaphore {
|
||||
Semaphore {
|
||||
lock: Mutex::new(count),
|
||||
cvar: Condvar::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Acquires a resource of this semaphore, blocking the current thread until
|
||||
/// it can do so.
|
||||
///
|
||||
/// This method will block until the internal count of the semaphore is at
|
||||
/// least 1.
|
||||
pub fn acquire(&self) {
|
||||
let mut count = self.lock.lock();
|
||||
while *count <= 0 {
|
||||
// TODO: -> cvar.wait(count)
|
||||
drop(count);
|
||||
self.cvar.wait();
|
||||
count = self.lock.lock();
|
||||
}
|
||||
*count -= 1;
|
||||
}
|
||||
|
||||
/// Release a resource from this semaphore.
|
||||
///
|
||||
/// This will increment the number of resources in this semaphore by 1 and
|
||||
/// will notify any pending waiters in `acquire` or `access` if necessary.
|
||||
pub fn release(&self) {
|
||||
*self.lock.lock() += 1;
|
||||
self.cvar.notify_one();
|
||||
}
|
||||
|
||||
/// Acquires a resource of this semaphore, returning an RAII guard to
|
||||
/// release the semaphore when dropped.
|
||||
///
|
||||
/// This function is semantically equivalent to an `acquire` followed by a
|
||||
/// `release` when the guard returned is dropped.
|
||||
pub fn access(&self) -> SemaphoreGuard {
|
||||
self.acquire();
|
||||
SemaphoreGuard { sem: self }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for SemaphoreGuard<'a> {
|
||||
fn drop(&mut self) {
|
||||
self.sem.release();
|
||||
}
|
||||
}
|
Loading…
Reference in new issue