[geary/mjog/invert-folder-class-hierarchy: 30/72] Geary.ImapEngine.ReplayQueue: Use a cancellable to manage running state
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/mjog/invert-folder-class-hierarchy: 30/72] Geary.ImapEngine.ReplayQueue: Use a cancellable to manage running state
- Date: Wed, 3 Mar 2021 11:52:44 +0000 (UTC)
commit 056226ffbe6e5de7acee4d24bb02a67343ae6c1d
Author: Michael Gratton <mike vee net>
Date: Tue Feb 16 09:02:08 2021 +1100
Geary.ImapEngine.ReplayQueue: Use a cancellable to manage running state
Use a cancellable instead of that and a boolean to determine if the
queue is running so a single object can be used to track it, the same
object can be passed to async calls, and it's easier to reason about
re-entrancy when interleaving start/stop calls.
.../imap-engine/imap-engine-replay-queue.vala | 39 ++++++++++++++--------
1 file changed, 26 insertions(+), 13 deletions(-)
---
diff --git a/src/engine/imap-engine/imap-engine-replay-queue.vala
b/src/engine/imap-engine/imap-engine-replay-queue.vala
index b1d0c7bef..cfeea3ba2 100644
--- a/src/engine/imap-engine/imap-engine-replay-queue.vala
+++ b/src/engine/imap-engine/imap-engine-replay-queue.vala
@@ -120,18 +120,22 @@ private class Geary.ImapEngine.ReplayQueue : BaseObject, Logging.Source {
}
private weak MinimalFolder owner;
+
private ReplayOperation? local_op_active = null;
private Nonblocking.Queue<ReplayOperation> local_queue =
new Nonblocking.Queue<ReplayOperation>.fifo();
- private bool remote_running = false;
+
private ReplayOperation? remote_op_active = null;
private Nonblocking.Queue<ReplayOperation> remote_queue =
new Nonblocking.Queue<ReplayOperation>.fifo();
+ private GLib.Cancellable remote_cancellable = new GLib.Cancellable();
+
private Gee.ArrayList<ReplayOperation> notification_queue = new Gee.ArrayList<ReplayOperation>();
private Scheduler.Scheduled? notification_timer = null;
+
private int64 next_submission_number = 0;
private State state = State.OPEN;
- private Cancellable remote_wait_cancellable = new Cancellable();
+
public virtual signal void scheduled(ReplayOperation op) {
debug("Scheduled: %s", op.to_string());
@@ -195,6 +199,9 @@ private class Geary.ImapEngine.ReplayQueue : BaseObject, Logging.Source {
public ReplayQueue(MinimalFolder owner) {
this.owner = owner;
this.do_replay_local_async.begin();
+
+ // Start off with the remote queue not running
+ this.remote_cancellable.cancel();
}
~ReplayQueue() {
@@ -205,15 +212,15 @@ private class Geary.ImapEngine.ReplayQueue : BaseObject, Logging.Source {
/** Starts the remote queue running */
public void start_remote() {
- if (!this.remote_running) {
- this.remote_running = true;
+ if (this.remote_cancellable.is_cancelled()) {
+ this.remote_cancellable = new GLib.Cancellable();
this.do_replay_remote_async.begin();
}
}
/** Starts the remote queue running */
public void stop_remote() {
- this.remote_running = false;
+ this.remote_cancellable.cancel();
}
/**
@@ -406,7 +413,7 @@ private class Geary.ImapEngine.ReplayQueue : BaseObject, Logging.Source {
// and clear out all waiting operations, backing out any that
// need to be backed out
if (!flush_pending) {
- this.remote_wait_cancellable.cancel();
+ this.remote_cancellable.cancel();
yield clear_pending_async(cancellable);
}
@@ -557,13 +564,16 @@ private class Geary.ImapEngine.ReplayQueue : BaseObject, Logging.Source {
}
private async void do_replay_remote_async() {
- while (this.remote_running) {
- // wait for the next operation ... do this *before*
+ while (!this.remote_cancellable.is_cancelled()) {
+ // Wait for the next operation ... do this *before*
// waiting for remote
ReplayOperation op;
try {
- op = yield this.remote_queue.peek();
- } catch (Error recv_err) {
+ op = yield this.remote_queue.peek(this.remote_cancellable);
+ } catch (GLib.IOError.CANCELLED err) {
+ // all good
+ break;
+ } catch (GLib.Error recv_err) {
warning(
"Unable to receive next replay operation on remote queue %s: %s", to_string(),
recv_err.message
@@ -576,13 +586,16 @@ private class Geary.ImapEngine.ReplayQueue : BaseObject, Logging.Source {
if (!is_close_op) {
try {
remote = yield owner.claim_remote_session(
- this.remote_wait_cancellable
+ this.remote_cancellable
);
yield this.remote_queue.receive();
+ } catch (GLib.IOError.CANCELLED err) {
+ // all good, just bail out
+ break;
} catch (GLib.Error remote_err) {
// Have to bail out completely if we can't get a
// remote, since any op that runs will fail
- this.remote_running = false;
+ this.remote_cancellable.cancel();
warning(
"Folder %s closed or failed to open, remote replay queue closing: %s",
to_string(),
@@ -591,7 +604,7 @@ private class Geary.ImapEngine.ReplayQueue : BaseObject, Logging.Source {
break;
}
} else {
- this.remote_running = false;
+ this.remote_cancellable.cancel();
}
this.remote_op_active = op;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]