Skip to content

Commit 3cdbe0d

Browse files
committed
common/timeout: expose Timeout for cross-module reuse
1 parent bc4bf5e commit 3cdbe0d

2 files changed

Lines changed: 42 additions & 12 deletions

File tree

src/common/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use tokio::io::{AsyncBufRead, AsyncRead, AsyncWrite, ReadBuf};
99
mod handshake;
1010
mod timeout;
1111
pub(crate) use handshake::{IoSession, MidHandshake};
12-
pub(crate) use timeout::HandshakeFuture;
12+
pub(crate) use timeout::{HandshakeFuture, Timeout};
1313

1414
#[derive(Debug)]
1515
pub(crate) enum TlsState {

src/common/timeout.rs

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ impl<IS: IoSession> HandshakeFuture<IS> {
2323
/// The deadline is fixed to `Instant::now() + duration` immediately, so the
2424
/// clock starts ticking when this is called, not when the future is first polled.
2525
pub(crate) fn new(inner: MidHandshake<IS>, timeout: Option<Duration>) -> Self {
26-
Self::from_deadline(inner, timeout.map(|d| Instant::now() + d))
26+
Self {
27+
inner,
28+
timeout: timeout.map(Timeout::from_duration),
29+
}
2730
}
2831

2932
/// Construct with an absolute `Instant` deadline.
@@ -33,10 +36,7 @@ impl<IS: IoSession> HandshakeFuture<IS> {
3336
pub(crate) fn from_deadline(inner: MidHandshake<IS>, deadline: Option<Instant>) -> Self {
3437
Self {
3538
inner,
36-
timeout: deadline.map(|deadline| Timeout {
37-
deadline,
38-
sleep: None,
39-
}),
39+
timeout: deadline.map(Timeout::from_deadline),
4040
}
4141
}
4242

@@ -65,11 +65,7 @@ where
6565
Some(timeout) => timeout,
6666
None => return Poll::Pending,
6767
};
68-
69-
let sleep = timeout
70-
.sleep
71-
.get_or_insert_with(|| Box::pin(sleep_until(timeout.deadline)));
72-
if sleep.as_mut().poll(cx).is_pending() {
68+
if timeout.poll_deadline(cx).is_pending() {
7369
return Poll::Pending;
7470
}
7571

@@ -87,7 +83,41 @@ where
8783
}
8884
}
8985

90-
struct Timeout {
86+
/// An absolute deadline paired with a lazily-initialized `Sleep` future.
87+
pub(crate) struct Timeout {
9188
deadline: Instant,
9289
sleep: Option<Pin<Box<Sleep>>>,
9390
}
91+
92+
impl Timeout {
93+
/// Construct from an absolute deadline.
94+
pub(crate) fn from_deadline(deadline: Instant) -> Self {
95+
Self {
96+
deadline,
97+
sleep: None,
98+
}
99+
}
100+
101+
/// Construct from a relative duration.
102+
///
103+
/// The deadline is fixed to `Instant::now() + duration` immediately.
104+
pub(crate) fn from_duration(duration: Duration) -> Self {
105+
Self::from_deadline(Instant::now() + duration)
106+
}
107+
108+
/// Poll the deadline.
109+
///
110+
/// Returns `Poll::Ready(())` once the deadline has elapsed; `Poll::Pending`
111+
/// otherwise. Lazily initializes the inner `Sleep` on first call.
112+
pub(crate) fn poll_deadline(&mut self, cx: &mut Context<'_>) -> Poll<()> {
113+
let sleep = self
114+
.sleep
115+
.get_or_insert_with(|| Box::pin(sleep_until(self.deadline)));
116+
sleep.as_mut().poll(cx)
117+
}
118+
119+
/// Return the absolute deadline.
120+
pub(crate) fn deadline(&self) -> Instant {
121+
self.deadline
122+
}
123+
}

0 commit comments

Comments
 (0)