Skip to content

Commit 47fc60b

Browse files
committed
fix: Use Instant instead of SystemTime when aplicable
If a time value doesn't need to be sent to another host, saved to the db or otherwise used across program restarts, a monotonically nondecreasing clock should be used.
1 parent 62c1237 commit 47fc60b

File tree

7 files changed

+21
-25
lines changed

7 files changed

+21
-25
lines changed

src/context.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::ops::Deref;
66
use std::path::{Path, PathBuf};
77
use std::sync::atomic::{AtomicBool, Ordering};
88
use std::sync::Arc;
9-
use std::time::{Duration, Instant, SystemTime};
9+
use std::time::{Duration, Instant};
1010

1111
use anyhow::{bail, ensure, Context as _, Result};
1212
use async_channel::{self as channel, Receiver, Sender};
@@ -232,7 +232,7 @@ pub struct InnerContext {
232232
/// be identified by this ID.
233233
pub(crate) id: u32,
234234

235-
creation_time: SystemTime,
235+
creation_time: Instant,
236236

237237
/// The text of the last error logged and emitted as an event.
238238
/// If the ui wants to display an error after a failure,
@@ -384,7 +384,7 @@ impl Context {
384384
resync_request: AtomicBool::new(false),
385385
new_msgs_notify,
386386
server_id: RwLock::new(None),
387-
creation_time: std::time::SystemTime::now(),
387+
creation_time: std::time::Instant::now(),
388388
last_full_folder_scan: Mutex::new(None),
389389
last_error: std::sync::RwLock::new("".to_string()),
390390
debug_logging: std::sync::RwLock::new(None),
@@ -790,7 +790,7 @@ impl Context {
790790
);
791791

792792
let elapsed = self.creation_time.elapsed();
793-
res.insert("uptime", duration_to_str(elapsed.unwrap_or_default()));
793+
res.insert("uptime", duration_to_str(elapsed));
794794

795795
Ok(res)
796796
}
@@ -1051,7 +1051,7 @@ pub fn get_version_str() -> &'static str {
10511051

10521052
#[cfg(test)]
10531053
mod tests {
1054-
use std::time::Duration;
1054+
use std::time::{Duration, SystemTime};
10551055

10561056
use anyhow::Context as _;
10571057
use strum::IntoEnumIterator;

src/imap/idle.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::time::{Duration, SystemTime};
1+
use std::time::{Duration, Instant};
22

33
use anyhow::{bail, Context as _, Result};
44
use async_channel::Receiver;
@@ -106,7 +106,7 @@ impl Imap {
106106
// Idle using polling. This is also needed if we're not yet configured -
107107
// in this case, we're waiting for a configure job (and an interrupt).
108108

109-
let fake_idle_start_time = SystemTime::now();
109+
let fake_idle_start_time = Instant::now();
110110

111111
// Do not poll, just wait for an interrupt when no folder is passed in.
112112
let watch_folder = if let Some(watch_folder) = watch_folder {
@@ -196,9 +196,8 @@ impl Imap {
196196
info!(
197197
context,
198198
"IMAP-fake-IDLE done after {:.4}s",
199-
SystemTime::now()
199+
Instant::now()
200200
.duration_since(fake_idle_start_time)
201-
.unwrap_or_default()
202201
.as_millis() as f64
203202
/ 1000.,
204203
);

src/key.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ async fn generate_keypair(context: &Context) -> Result<KeyPair> {
207207
match load_keypair(context, &addr).await? {
208208
Some(key_pair) => Ok(key_pair),
209209
None => {
210-
let start = std::time::SystemTime::now();
210+
let start = std::time::Instant::now();
211211
let keytype = KeyGenType::from_i32(context.get_config_int(Config::KeyGenType).await?)
212212
.unwrap_or_default();
213213
info!(context, "Generating keypair with type {}", keytype);
@@ -219,7 +219,7 @@ async fn generate_keypair(context: &Context) -> Result<KeyPair> {
219219
info!(
220220
context,
221221
"Keypair generated in {:.3}s.",
222-
start.elapsed().unwrap_or_default().as_secs()
222+
start.elapsed().as_secs(),
223223
);
224224
Ok(keypair)
225225
}

src/quota.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! # Support for IMAP QUOTA extension.
22
33
use std::collections::BTreeMap;
4+
use std::time::Instant;
45

56
use anyhow::{anyhow, Context as _, Result};
67
use async_imap::types::{Quota, QuotaResource};
@@ -12,7 +13,6 @@ use crate::imap::scan_folders::get_watched_folders;
1213
use crate::imap::session::Session as ImapSession;
1314
use crate::imap::Imap;
1415
use crate::message::{Message, Viewtype};
15-
use crate::tools::time;
1616
use crate::{stock_str, EventType};
1717

1818
/// warn about a nearly full mailbox after this usage percentage is reached.
@@ -40,8 +40,8 @@ pub struct QuotaInfo {
4040
/// set to `Ok()` for valid quota information.
4141
pub(crate) recent: Result<BTreeMap<String, Vec<QuotaResource>>>,
4242

43-
/// Timestamp when structure was modified.
44-
pub(crate) modified: i64,
43+
/// When the structure was modified.
44+
pub(crate) modified: Instant,
4545
}
4646

4747
async fn get_unique_quota_roots_and_usage(
@@ -147,7 +147,7 @@ impl Context {
147147

148148
*self.quota.write().await = Some(QuotaInfo {
149149
recent: quota,
150-
modified: time(),
150+
modified: Instant::now(),
151151
});
152152

153153
self.emit_event(EventType::ConnectivityChanged);

src/scheduler.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::cmp;
22
use std::iter::{self, once};
33
use std::num::NonZeroUsize;
44
use std::sync::atomic::Ordering;
5+
use std::time::Duration;
56

67
use anyhow::{bail, Context as _, Error, Result};
78
use async_channel::{self as channel, Receiver, Sender};
@@ -384,7 +385,7 @@ async fn inbox_loop(
384385
let quota = ctx.quota.read().await;
385386
quota
386387
.as_ref()
387-
.filter(|quota| quota.modified + 60 > time())
388+
.filter(|quota| quota.modified.elapsed() > Duration::from_secs(60))
388389
.is_none()
389390
};
390391

src/smtp.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
pub mod send;
44

5-
use std::time::{Duration, SystemTime};
5+
use std::time::{Duration, Instant};
66

77
use anyhow::{bail, format_err, Context as _, Error, Result};
88
use async_smtp::response::{Category, Code, Detail};
@@ -41,7 +41,7 @@ pub(crate) struct Smtp {
4141
/// Timestamp of last successful send/receive network interaction
4242
/// (eg connect or send succeeded). On initialization and disconnect
4343
/// it is set to None.
44-
last_success: Option<SystemTime>,
44+
last_success: Option<Instant>,
4545

4646
pub(crate) connectivity: ConnectivityStore,
4747

@@ -70,11 +70,7 @@ impl Smtp {
7070
/// have been successfully used the last 60 seconds
7171
pub fn has_maybe_stale_connection(&self) -> bool {
7272
if let Some(last_success) = self.last_success {
73-
SystemTime::now()
74-
.duration_since(last_success)
75-
.unwrap_or_default()
76-
.as_secs()
77-
> 60
73+
Instant::now().duration_since(last_success).as_secs() > 60
7874
} else {
7975
false
8076
}
@@ -334,7 +330,7 @@ impl Smtp {
334330
}
335331

336332
self.transport = Some(transport);
337-
self.last_success = Some(SystemTime::now());
333+
self.last_success = Some(Instant::now());
338334

339335
context.emit_event(EventType::SmtpConnected(format!(
340336
"SMTP-LOGIN as {} ok",

src/smtp/send.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ impl Smtp {
6969
);
7070
info!(context, "{info_msg}.");
7171
context.emit_event(EventType::SmtpMessageSent(info_msg));
72-
self.last_success = Some(std::time::SystemTime::now());
72+
self.last_success = Some(std::time::Instant::now());
7373
} else {
7474
warn!(
7575
context,

0 commit comments

Comments
 (0)