Fix sync loop watcher ABA.

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk
2025-08-05 09:28:02 +00:00
parent fa84a7e6c2
commit 8a8a5d598e

View File

@@ -156,10 +156,12 @@ pub(crate) async fn sync_events_route(
.checked_add(Duration::from_millis(timeout))
.expect("configuration must limit maximum timeout");
let mut next_batch = services.globals.current_count();
loop {
// Listen for activity
let watchers = services.sync.watch(sender_user, sender_device);
let next_batch = services.globals.wait_pending().await?;
debug_assert!(since <= next_batch, "next_batch is monotonic");
if since < next_batch || body.body.full_state {
// Check for activity
let response = build_sync_events(&services, &body, since, next_batch).await?;
@@ -176,7 +178,8 @@ pub(crate) async fn sync_events_route(
// Wait for activity
if time::timeout_at(stop_at, watchers).await.is_err() {
break;
trace!(next_batch, "empty response");
return Ok(sync_events::v3::Response::new(next_batch.to_string()));
}
trace!(
@@ -184,16 +187,9 @@ pub(crate) async fn sync_events_route(
last_batch = ?next_batch,
count = ?services.globals.pending_count(),
stop_at = ?stop_at,
"waited for watchers"
"notified by watcher"
);
// Synchronize activity
next_batch = services.globals.wait_pending().await?;
debug_assert!(since <= next_batch, "next_batch is monotonic");
}
trace!(next_batch, "empty response");
return Ok(sync_events::v3::Response::new(next_batch.to_string()));
}
#[tracing::instrument(