[geary/mjog/imap-command-cancellation: 5/6] Geary.Imap.Command: Improve cancelled-before send handling
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/mjog/imap-command-cancellation: 5/6] Geary.Imap.Command: Improve cancelled-before send handling
- Date: Wed, 2 Sep 2020 06:03:49 +0000 (UTC)
commit a1b0547e67e77f0b10fb6877512599c6d790fdf6
Author: Michael Gratton <mike vee net>
Date: Wed Sep 2 11:07:58 2020 +1000
Geary.Imap.Command: Improve cancelled-before send handling
Add `cancelled_before_send` method to support explicitly cancelling the
command before it was sent, so that `wait_until_complete` does not end
up waiting forever when this happens. Call the new method from
`ClientConnection` as required.
src/engine/imap/command/imap-command.vala | 40 +++++++++++++++-------
.../imap/transport/imap-client-connection.vala | 2 ++
2 files changed, 30 insertions(+), 12 deletions(-)
---
diff --git a/src/engine/imap/command/imap-command.vala b/src/engine/imap/command/imap-command.vala
index 702ce1af8..caa40e511 100644
--- a/src/engine/imap/command/imap-command.vala
+++ b/src/engine/imap/command/imap-command.vala
@@ -92,7 +92,7 @@ public abstract class Geary.Imap.Command : BaseObject {
private Geary.Nonblocking.Semaphore complete_lock =
new Geary.Nonblocking.Semaphore();
- private ImapError? cancelled_cause = null;
+ private GLib.Error? cancelled_cause = null;
private Geary.Nonblocking.Spinlock? literal_spinlock = null;
private GLib.Cancellable? literal_cancellable = null;
@@ -277,6 +277,16 @@ public abstract class Geary.Imap.Command : BaseObject {
throw this.cancelled_cause;
}
+ // If everything above is fine, but sending was cancelled, it
+ // must have been cancelled after being sent. Throw an error
+ // indicating this specifically.
+ if (this.should_send != null &&
+ this.should_send.is_cancelled()) {
+ throw new GLib.IOError.CANCELLED(
+ "Command was cancelled after sending: %s", to_brief_string()
+ );
+ }
+
check_has_status();
// Since this is part of the public API, perform a strict
@@ -288,15 +298,6 @@ public abstract class Geary.Imap.Command : BaseObject {
this.status.to_string()
);
}
-
- // If everything else looks fine, but sending was cancelled,
- // throw an error here so the caller knows that was the case.
- if (this.should_send != null &&
- this.should_send.is_cancelled()) {
- throw new GLib.IOError.CANCELLED(
- "Sent command was cancelled: %s", to_brief_string()
- );
- }
}
public virtual string to_string() {
@@ -332,12 +333,27 @@ public abstract class Geary.Imap.Command : BaseObject {
}
/**
- * Cancels this command due to a network or server disconnect.
+ * Marks this command as being cancelled before being sent.
*
* When this method is called, all locks will be released,
* including {@link wait_until_complete}, which will then throw a
* `GLib.IOError.CANCELLED` error.
*/
+ internal virtual void cancelled_before_send() {
+ cancel(
+ new GLib.IOError.CANCELLED(
+ "Command was cancelled before sending: %s", to_brief_string()
+ )
+ );
+ }
+
+ /**
+ * Cancels this command due to a network or server disconnect.
+ *
+ * When this method is called, all locks will be released,
+ * including {@link wait_until_complete}, which will then throw a
+ * `ImapError.NOT_CONNECTED` error.
+ */
internal virtual void disconnected(string reason) {
cancel(new ImapError.NOT_CONNECTED("%s: %s", to_brief_string(), reason));
}
@@ -406,7 +422,7 @@ public abstract class Geary.Imap.Command : BaseObject {
}
}
- private void cancel(ImapError cause) {
+ private void cancel(GLib.Error cause) {
stop_serialisation();
this.cancelled_cause = cause;
this.response_timer.reset();
diff --git a/src/engine/imap/transport/imap-client-connection.vala
b/src/engine/imap/transport/imap-client-connection.vala
index debb843db..390984e94 100644
--- a/src/engine/imap/transport/imap-client-connection.vala
+++ b/src/engine/imap/transport/imap-client-connection.vala
@@ -265,6 +265,7 @@ public class Geary.Imap.ClientConnection : BaseObject, Logging.Source {
check_connection();
if (new_command.should_send != null &&
new_command.should_send.is_cancelled()) {
+ new_command.cancelled_before_send();
throw new GLib.IOError.CANCELLED(
"Not queuing command, sending is cancelled: %s",
new_command.to_brief_string()
@@ -437,6 +438,7 @@ public class Geary.Imap.ClientConnection : BaseObject, Logging.Source {
throws GLib.Error {
if (command.should_send != null &&
command.should_send.is_cancelled()) {
+ command.cancelled_before_send();
throw new GLib.IOError.CANCELLED(
"Not sending command, sending is cancelled: %s",
command.to_brief_string()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]