1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
//! Helpers for reporting information about guard status to the guard manager.
use std::sync::Mutex;
use tor_guardmgr::{GuardMonitor, GuardStatus};
use tor_proto::ClockSkew;
/// A shareable object that we can use to report guard status to the guard
/// manager.
pub(crate) struct GuardStatusHandle {
/// An inner guard monitor.
///
/// If this is None, then either we aren't using the guard
/// manager, or we already reported a status to it.
mon: Mutex<Option<GuardMonitor>>,
}
impl From<Option<GuardMonitor>> for GuardStatusHandle {
fn from(mon: Option<GuardMonitor>) -> Self {
Self {
mon: Mutex::new(mon),
}
}
}
impl GuardStatusHandle {
/// Finalize this guard status handle, and report its pending status
/// to the guard manager.
///
/// Future calls to methods on this object will do nothing.
pub(crate) fn commit(&self) {
let mut mon = self.mon.lock().expect("Poisoned lock");
if let Some(mon) = mon.take() {
mon.commit();
}
}
/// Change the pending status on this guard.
///
/// Note that the pending status will not be sent to the guard manager
/// immediately: only committing this GuardStatusHandle, or dropping it,
/// will do so.
pub(crate) fn pending(&self, status: GuardStatus) {
let mut mon = self.mon.lock().expect("Poisoned lock");
if let Some(mon) = mon.as_mut() {
mon.pending_status(status);
}
}
/// Change the pending clock skew for this guard.
///
/// As with pending status, this value won't be sent to the guard manager
/// until this `GuardStatusHandle` is dropped or committed.
pub(crate) fn skew(&self, skew: ClockSkew) {
let mut mon = self.mon.lock().expect("Poisoned lock");
if let Some(mon) = mon.as_mut() {
mon.skew(skew);
}
}
/// Report the provided status to the guard manager.
///
/// Future calls to methods on this object will do nothing.
pub(crate) fn report(&self, status: GuardStatus) {
let mut mon = self.mon.lock().expect("Poisoned lock");
if let Some(mon) = mon.take() {
mon.report(status);
}
}
}