use std::sync::Arc;
use std::time::Duration;
use crate::reason::ShutdownReason;
use crate::state::Inner;
#[derive(Debug, Clone)]
pub struct ShutdownToken {
inner: Arc<Inner>,
}
impl ShutdownToken {
pub(crate) fn new(inner: Arc<Inner>) -> Self {
Self { inner }
}
#[must_use]
pub fn is_initiated(&self) -> bool {
self.inner.is_initiated()
}
#[must_use]
pub fn reason(&self) -> Option<ShutdownReason> {
self.inner.reason()
}
#[must_use]
pub fn elapsed(&self) -> Option<Duration> {
self.inner.elapsed()
}
pub fn wait_blocking(&self) {
self.inner.wait_blocking();
}
pub fn wait_blocking_timeout(&self, timeout: Duration) -> bool {
self.inner.wait_blocking_timeout(timeout)
}
#[cfg(feature = "tokio")]
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
pub async fn wait(&self) {
if self.inner.is_initiated() {
return;
}
let mut rx = self.inner.tx.subscribe();
if self.inner.is_initiated() {
return;
}
let _ = rx.recv().await;
}
#[cfg(all(feature = "async-std", not(feature = "tokio")))]
#[cfg_attr(docsrs, doc(cfg(feature = "async-std")))]
pub async fn wait(&self) {
let mut poll = Duration::from_millis(1);
let cap = Duration::from_millis(50);
while !self.inner.is_initiated() {
async_std::task::sleep(poll).await;
poll = (poll * 2).min(cap);
}
}
}
#[derive(Debug, Clone)]
pub struct ShutdownTrigger {
inner: Arc<Inner>,
}
impl ShutdownTrigger {
pub(crate) fn new(inner: Arc<Inner>) -> Self {
Self { inner }
}
pub fn trigger(&self, reason: ShutdownReason) -> bool {
self.inner.trigger(reason)
}
#[must_use]
pub fn is_initiated(&self) -> bool {
self.inner.is_initiated()
}
}