1use std::sync::Arc;
4use std::time::Duration;
5
6use crate::reason::ShutdownReason;
7use crate::state::Inner;
8
9#[derive(Debug, Clone)]
14pub struct ShutdownToken {
15 inner: Arc<Inner>,
16}
17
18impl ShutdownToken {
19 pub(crate) fn new(inner: Arc<Inner>) -> Self {
20 Self { inner }
21 }
22
23 #[must_use]
25 pub fn is_initiated(&self) -> bool {
26 self.inner.is_initiated()
27 }
28
29 #[must_use]
31 pub fn reason(&self) -> Option<ShutdownReason> {
32 self.inner.reason()
33 }
34
35 #[must_use]
37 pub fn elapsed(&self) -> Option<Duration> {
38 self.inner.elapsed()
39 }
40
41 pub fn wait_blocking(&self) {
45 self.inner.wait_blocking();
46 }
47
48 pub fn wait_blocking_timeout(&self, timeout: Duration) -> bool {
53 self.inner.wait_blocking_timeout(timeout)
54 }
55
56 #[cfg(feature = "tokio")]
61 #[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
62 pub async fn wait(&self) {
63 if self.inner.is_initiated() {
64 return;
65 }
66 let mut rx = self.inner.tx.subscribe();
67 if self.inner.is_initiated() {
68 return;
69 }
70 let _ = rx.recv().await;
71 }
72
73 #[cfg(all(feature = "async-std", not(feature = "tokio")))]
78 #[cfg_attr(docsrs, doc(cfg(feature = "async-std")))]
79 pub async fn wait(&self) {
80 let mut poll = Duration::from_millis(1);
81 let cap = Duration::from_millis(50);
82 while !self.inner.is_initiated() {
83 async_std::task::sleep(poll).await;
84 poll = (poll * 2).min(cap);
85 }
86 }
87}
88
89#[derive(Debug, Clone)]
94pub struct ShutdownTrigger {
95 inner: Arc<Inner>,
96}
97
98impl ShutdownTrigger {
99 pub(crate) fn new(inner: Arc<Inner>) -> Self {
100 Self { inner }
101 }
102
103 pub fn trigger(&self, reason: ShutdownReason) -> bool {
108 self.inner.trigger(reason)
109 }
110
111 #[must_use]
113 pub fn is_initiated(&self) -> bool {
114 self.inner.is_initiated()
115 }
116}