1
//! Helpers for reporting information about guard status to the guard manager.
2

            
3
use std::sync::Mutex;
4
use tor_guardmgr::{GuardMonitor, GuardStatus};
5

            
6
/// A shareable object that we can use to report guard status to the guard
7
/// manager.
8
pub(crate) struct GuardStatusHandle {
9
    /// An inner guard monitor.
10
    ///
11
    /// If this is None, then either we aren't using the guard
12
    /// manager, or we already reported a status to it.
13
    mon: Mutex<Option<GuardMonitor>>,
14
}
15

            
16
impl From<Option<GuardMonitor>> for GuardStatusHandle {
17
16
    fn from(mon: Option<GuardMonitor>) -> Self {
18
16
        Self {
19
16
            mon: Mutex::new(mon),
20
16
        }
21
16
    }
22
}
23

            
24
impl GuardStatusHandle {
25
    /// Finalize this guard status handle, and report its pending status
26
    /// to the guard manager.
27
    ///
28
    /// Future calls to methods on this object will do nothing.
29
    pub(crate) fn commit(&self) {
30
        let mut mon = self.mon.lock().expect("Poisoned lock");
31
        if let Some(mon) = mon.take() {
32
            mon.commit();
33
        }
34
    }
35

            
36
    /// Change the pending status on this guard.
37
    ///
38
    /// Note that the pending status will not be sent to the guard manager
39
    /// immediately: only committing this GuardStatusHandle, or dropping it,
40
    /// will do so.
41
28
    pub(crate) fn pending(&self, status: GuardStatus) {
42
28
        let mut mon = self.mon.lock().expect("Poisoned lock");
43
28
        if let Some(mon) = mon.as_mut() {
44
            mon.pending_status(status);
45
28
        }
46
28
    }
47

            
48
    /// Report the provided status to the guard manager.
49
    ///
50
    /// Future calls to methods on this object will do nothing.
51
    pub(crate) fn report(&self, status: GuardStatus) {
52
        let mut mon = self.mon.lock().expect("Poisoned lock");
53
        if let Some(mon) = mon.take() {
54
            mon.report(status);
55
        }
56
    }
57
}