mirror of
https://github.com/chatmail/core.git
synced 2026-05-22 16:26:31 +03:00
fix: await the tasks after aborting them
This commit is contained in:
@@ -167,12 +167,17 @@ impl Accounts {
|
|||||||
.with_context(|| format!("no account with id {id}"))?;
|
.with_context(|| format!("no account with id {id}"))?;
|
||||||
ctx.stop_io().await;
|
ctx.stop_io().await;
|
||||||
|
|
||||||
// Explicitly close the database.
|
// Explicitly close the database
|
||||||
|
// to make sure the database file is closed
|
||||||
|
// and can be removed on Windows.
|
||||||
|
// If some spawned task tries to use the database afterwards,
|
||||||
|
// it will fail.
|
||||||
//
|
//
|
||||||
// Stopping I/O aborts the tasks that keep `Context` clones,
|
// Previously `stop_io()` aborted the tasks without awaiting them
|
||||||
// but aborting the task does not immediately drops the future.
|
// and this resulted in keeping `Context` clones inside
|
||||||
// To make sure the database file is closed
|
// `Future`s that were not dropped. This bug is fixed now,
|
||||||
// and can be removed on Windows, we drop all the connections manually.
|
// but explicitly closing the database ensures that file is freed
|
||||||
|
// even if not all `Context` references are dropped.
|
||||||
ctx.sql.close().await;
|
ctx.sql.close().await;
|
||||||
drop(ctx);
|
drop(ctx);
|
||||||
|
|
||||||
|
|||||||
@@ -1913,8 +1913,13 @@ impl RecentlySeenLoop {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn abort(self) {
|
pub(crate) async fn abort(self) {
|
||||||
self.handle.abort();
|
self.handle.abort();
|
||||||
|
|
||||||
|
// Await aborted task to ensure the `Future` is dropped
|
||||||
|
// with all resources moved inside such as the `Context`
|
||||||
|
// reference to `InnerContext`.
|
||||||
|
self.handle.await.ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,13 +110,14 @@ impl SchedulerState {
|
|||||||
// to allow for clean shutdown.
|
// to allow for clean shutdown.
|
||||||
context.new_msgs_notify.notify_one();
|
context.new_msgs_notify.notify_one();
|
||||||
|
|
||||||
if let Some(debug_logging) = context
|
let debug_logging = context
|
||||||
.debug_logging
|
.debug_logging
|
||||||
.read()
|
.write()
|
||||||
.expect("RwLock is poisoned")
|
.expect("RwLock is poisoned")
|
||||||
.as_ref()
|
.take();
|
||||||
{
|
if let Some(debug_logging) = debug_logging {
|
||||||
debug_logging.loop_handle.abort();
|
debug_logging.loop_handle.abort();
|
||||||
|
debug_logging.loop_handle.await.ok();
|
||||||
}
|
}
|
||||||
let prev_state = std::mem::replace(&mut *inner, new_state);
|
let prev_state = std::mem::replace(&mut *inner, new_state);
|
||||||
context.emit_event(EventType::ConnectivityChanged);
|
context.emit_event(EventType::ConnectivityChanged);
|
||||||
@@ -974,9 +975,16 @@ impl Scheduler {
|
|||||||
.await
|
.await
|
||||||
.log_err(context)
|
.log_err(context)
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
|
// Abort tasks, then await them to ensure the `Future` is dropped.
|
||||||
|
// Just aborting the task may keep resources such as `Context` clone
|
||||||
|
// moved into it indefinitely, resulting in database not being
|
||||||
|
// closed etc.
|
||||||
self.ephemeral_handle.abort();
|
self.ephemeral_handle.abort();
|
||||||
|
self.ephemeral_handle.await.ok();
|
||||||
self.location_handle.abort();
|
self.location_handle.abort();
|
||||||
self.recently_seen_loop.abort();
|
self.location_handle.await.ok();
|
||||||
|
self.recently_seen_loop.abort().await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user