Skip to content

Commit 3d64d75

Browse files
committed
feat: Cache system time instead of looking at the clock several times in a row
The system clock may be adjusted and even go back, so caching system time in code sections where it's not supposed to change may even protect from races/bugs.
1 parent 3a9d1e9 commit 3d64d75

File tree

5 files changed

+32
-15
lines changed

5 files changed

+32
-15
lines changed

src/chat.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2792,12 +2792,14 @@ pub(crate) async fn create_send_msg_job(
27922792
);
27932793
}
27942794

2795+
let now = time();
2796+
27952797
if rendered_msg.is_gossiped {
2796-
msg.chat_id.set_gossiped_timestamp(context, time()).await?;
2798+
msg.chat_id.set_gossiped_timestamp(context, now).await?;
27972799
}
27982800

27992801
if let Some(last_added_location_id) = rendered_msg.last_added_location_id {
2800-
if let Err(err) = location::set_kml_sent_timestamp(context, msg.chat_id, time()).await {
2802+
if let Err(err) = location::set_kml_sent_timestamp(context, msg.chat_id, now).await {
28012803
error!(context, "Failed to set kml sent_timestamp: {err:#}.");
28022804
}
28032805
if !msg.hidden {
@@ -2816,7 +2818,7 @@ pub(crate) async fn create_send_msg_job(
28162818
}
28172819

28182820
if attach_selfavatar {
2819-
if let Err(err) = msg.chat_id.set_selfavatar_timestamp(context, time()).await {
2821+
if let Err(err) = msg.chat_id.set_selfavatar_timestamp(context, now).await {
28202822
error!(context, "Failed to set selfavatar timestamp: {err:#}.");
28212823
}
28222824
}

src/contact.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,6 +1692,12 @@ impl RecentlySeenLoop {
16921692
async fn run(context: Context, interrupt: Receiver<RecentlySeenInterrupt>) {
16931693
type MyHeapElem = (Reverse<i64>, ContactId);
16941694

1695+
let now = SystemTime::now();
1696+
let now_ts = now
1697+
.duration_since(SystemTime::UNIX_EPOCH)
1698+
.unwrap_or_default()
1699+
.as_secs() as i64;
1700+
16951701
// Priority contains all recently seen sorted by the timestamp
16961702
// when they become not recently seen.
16971703
//
@@ -1702,7 +1708,7 @@ impl RecentlySeenLoop {
17021708
.query_map(
17031709
"SELECT id, last_seen FROM contacts
17041710
WHERE last_seen > ?",
1705-
(time() - SEEN_RECENTLY_SECONDS,),
1711+
(now_ts - SEEN_RECENTLY_SECONDS,),
17061712
|row| {
17071713
let contact_id: ContactId = row.get("id")?;
17081714
let last_seen: i64 = row.get("last_seen")?;
@@ -1717,8 +1723,6 @@ impl RecentlySeenLoop {
17171723
.unwrap_or_default();
17181724

17191725
loop {
1720-
let now = SystemTime::now();
1721-
17221726
let (until, contact_id) =
17231727
if let Some((Reverse(timestamp), contact_id)) = unseen_queue.peek() {
17241728
(

src/imex.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ async fn export_backup(context: &Context, dir: &Path, passphrase: String) -> Res
526526
let _d1 = DeleteOnDrop(temp_db_path.clone());
527527
let _d2 = DeleteOnDrop(temp_path.clone());
528528

529-
export_database(context, &temp_db_path, passphrase)
529+
export_database(context, &temp_db_path, passphrase, now)
530530
.await
531531
.context("could not export database")?;
532532

@@ -762,19 +762,27 @@ where
762762
/// overwritten.
763763
///
764764
/// This also verifies that IO is not running during the export.
765-
async fn export_database(context: &Context, dest: &Path, passphrase: String) -> Result<()> {
765+
async fn export_database(
766+
context: &Context,
767+
dest: &Path,
768+
passphrase: String,
769+
timestamp: i64,
770+
) -> Result<()> {
766771
ensure!(
767772
!context.scheduler.is_running().await,
768773
"cannot export backup, IO is running"
769774
);
770-
let now = time().try_into().context("32-bit UNIX time overflow")?;
775+
let timestamp = timestamp.try_into().context("32-bit UNIX time overflow")?;
771776

772777
// TODO: Maybe introduce camino crate for UTF-8 paths where we need them.
773778
let dest = dest
774779
.to_str()
775780
.with_context(|| format!("path {} is not valid unicode", dest.display()))?;
776781

777-
context.sql.set_raw_config_int("backup_time", now).await?;
782+
context
783+
.sql
784+
.set_raw_config_int("backup_time", timestamp)
785+
.await?;
778786
sql::housekeeping(context).await.log_err(context).ok();
779787
context
780788
.sql

src/imex/transfer.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ use crate::context::Context;
5252
use crate::message::{Message, Viewtype};
5353
use crate::qr::{self, Qr};
5454
use crate::stock_str::backup_transfer_msg_body;
55+
use crate::tools::time;
5556
use crate::{e2ee, EventType};
5657

5758
use super::{export_database, DBFILE_BACKUP_NAME};
@@ -158,7 +159,7 @@ impl BackupProvider {
158159
// Generate the token up front: we also use it to encrypt the database.
159160
let token = AuthToken::generate();
160161
context.emit_event(SendProgress::Started.into());
161-
export_database(context, dbfile, token.to_string())
162+
export_database(context, dbfile, token.to_string(), time())
162163
.await
163164
.context("Database export failed")?;
164165
context.emit_event(SendProgress::DatabaseExported.into());

src/location.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,9 @@ impl Kml {
139139
match chrono::NaiveDateTime::parse_from_str(&val, "%Y-%m-%dT%H:%M:%SZ") {
140140
Ok(res) => {
141141
self.curr.timestamp = res.timestamp();
142-
if self.curr.timestamp > time() {
143-
self.curr.timestamp = time();
142+
let now = time();
143+
if self.curr.timestamp > now {
144+
self.curr.timestamp = now;
144145
}
145146
}
146147
Err(_err) => {
@@ -333,12 +334,13 @@ pub async fn set(context: &Context, latitude: f64, longitude: f64, accuracy: f64
333334
return Ok(true);
334335
}
335336
let mut continue_streaming = false;
337+
let now = time();
336338

337339
let chats = context
338340
.sql
339341
.query_map(
340342
"SELECT id FROM chats WHERE locations_send_until>?;",
341-
(time(),),
343+
(now,),
342344
|row| row.get::<_, i32>(0),
343345
|chats| {
344346
chats
@@ -356,7 +358,7 @@ pub async fn set(context: &Context, latitude: f64, longitude: f64, accuracy: f64
356358
latitude,
357359
longitude,
358360
accuracy,
359-
time(),
361+
now,
360362
chat_id,
361363
ContactId::SELF,
362364
)).await.context("Failed to store location")?;

0 commit comments

Comments
 (0)