semaphore/
shutdown.rs

1use std::sync::Arc;
2
3use raw::RawSemaphore;
4
5/// Handle representing the shutdown process of a semaphore,
6/// allowing for extraction of the underlying resource.
7///
8/// Returned from `Semaphore::shutdown`. 
9pub struct ShutdownHandle<T> {
10    raw: Arc<RawSemaphore>,
11    resource: Option<Arc<T>>
12}
13
14pub fn new<T>(raw: &Arc<RawSemaphore>, resource: Option<Arc<T>>) -> ShutdownHandle<T> {
15    ShutdownHandle {
16        raw: raw.clone(),
17        resource: resource
18    }
19}
20
21impl<T> ShutdownHandle<T> {
22    /// Block until all access has been released to the semaphore,
23    /// and extract the underlying resource.
24    ///
25    /// When `Semaphore::shutdown` has been called multiple times,
26    /// only the first shutdown handle will return the resource.
27    /// All others will return `None`.
28    pub fn wait(self) -> Option<T> {
29        self.raw.wait_until_inactive();
30        self.resource.map(|mut arc| {
31            loop {
32                match Arc::try_unwrap(arc) {
33                    Ok(resource) => {
34                        return resource;
35                    },
36                    Err(returned_arc) => {
37                        arc = returned_arc;
38                    }
39                }
40            }
41        })
42    }
43
44    #[doc(hidden)]
45    pub fn is_complete(&self) -> bool {
46        !self.raw.is_active()
47    }
48}