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.
This commit is contained in:
parent
6c0607d809
commit
a1b0547e67
2 changed files with 30 additions and 12 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue