[geary] Additional debug logging at app shutdown for bug #745561
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary] Additional debug logging at app shutdown for bug #745561
- Date: Thu, 5 Mar 2015 23:55:50 +0000 (UTC)
commit 7494fa57d2307379842334042b312f406632277c
Author: Jim Nelson <jim yorba org>
Date: Thu Mar 5 15:55:05 2015 -0800
Additional debug logging at app shutdown for bug #745561
Hopefully these messages will give us some idea where in the shutdown
code the application sometimes hangs.
src/client/application/geary-controller.vala | 24 +++++++++++++++++--
src/engine/api/geary-abstract-local-folder.vala | 6 +++-
src/engine/api/geary-folder.vala | 9 +++++--
src/engine/app/app-conversation-monitor.vala | 12 +++++++--
.../imap-engine/imap-engine-minimal-folder.vala | 12 ++++++---
.../replay-ops/imap-engine-user-close.vala | 4 ++-
6 files changed, 51 insertions(+), 16 deletions(-)
---
diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala
index c60574c..740ee78 100644
--- a/src/client/application/geary-controller.vala
+++ b/src/client/application/geary-controller.vala
@@ -269,14 +269,21 @@ public class GearyController : Geary.BaseObject {
// close the ConversationMonitor
try {
if (current_conversations != null) {
- yield current_conversations.stop_monitoring_async(null);
+ debug("Stopping conversation monitor for %s...", current_conversations.folder.to_string());
+
+ bool closing = yield current_conversations.stop_monitoring_async(null);
// If not an Inbox, wait for it to close so all pending operations are flushed
- if (!inboxes.values.contains(current_conversations.folder))
+ if (closing) {
+ debug("Waiting for %s to close...", current_conversations.folder.to_string());
yield current_conversations.folder.wait_for_close_async(null);
+ }
+
+ debug("Stopped conversation monitor for %s", current_conversations.folder.to_string());
}
} catch (Error err) {
- message("Error closing conversation at shutdown: %s", err.message);
+ message("Error closing conversation monitor %s at shutdown: %s",
+ current_conversations.folder.to_string(), err.message);
} finally {
current_conversations = null;
}
@@ -284,9 +291,16 @@ public class GearyController : Geary.BaseObject {
// close all Inboxes
foreach (Geary.Folder inbox in inboxes.values) {
try {
+ debug("Closing %s...", inbox.to_string());
+
// close and wait for all pending operations to be flushed
yield inbox.close_async(null);
+
+ debug("Waiting for %s to close completely...", inbox.to_string());
+
yield inbox.wait_for_close_async(null);
+
+ debug("Closed %s", inbox.to_string());
} catch (Error err) {
message("Error closing Inbox %s at shutdown: %s", inbox.to_string(), err.message);
}
@@ -295,7 +309,9 @@ public class GearyController : Geary.BaseObject {
// close all Accounts
foreach (Geary.Account account in email_stores.keys) {
try {
+ debug("Closing account %s", account.to_string());
yield account.close_async(null);
+ debug("Closed account %s", account.to_string());
} catch (Error err) {
message("Error closing account %s at shutdown: %s", account.to_string(), err.message);
}
@@ -305,7 +321,9 @@ public class GearyController : Geary.BaseObject {
// Turn off the lights and lock the door behind you
try {
+ debug("Closing Engine...");
yield Geary.Engine.instance.close_async(null);
+ debug("Closed Engine");
} catch (Error err) {
message("Error closing Geary Engine instance: %s", err.message);
}
diff --git a/src/engine/api/geary-abstract-local-folder.vala b/src/engine/api/geary-abstract-local-folder.vala
index 05a062f..74f1add 100644
--- a/src/engine/api/geary-abstract-local-folder.vala
+++ b/src/engine/api/geary-abstract-local-folder.vala
@@ -47,14 +47,16 @@ public abstract class Geary.AbstractLocalFolder : Geary.Folder {
return true;
}
- public override async void close_async(Cancellable? cancellable = null) throws Error {
+ public override async bool close_async(Cancellable? cancellable = null) throws Error {
if (open_count == 0 || --open_count > 0)
- return;
+ return false;
closed_semaphore.blind_notify();
notify_closed(Geary.Folder.CloseReason.LOCAL_CLOSE);
notify_closed(Geary.Folder.CloseReason.FOLDER_CLOSED);
+
+ return false;
}
public override async void wait_for_close_async(Cancellable? cancellable = null) throws Error {
diff --git a/src/engine/api/geary-folder.vala b/src/engine/api/geary-folder.vala
index 7b213c3..bb8abe8 100644
--- a/src/engine/api/geary-folder.vala
+++ b/src/engine/api/geary-folder.vala
@@ -452,12 +452,15 @@ public abstract class Geary.Folder : BaseObject {
* tearing down network connections, closing files, and so forth. See "closed" for signals
* indicating the closing states.
*
- * If the Folder is already closed, the method silently returns.
+ * Returns true if the open count decrements to zero and the folder is ''closing''. Use
+ * { link wait_for_close_async} to block until the folder is completely closed. Otherwise,
+ * returns false. Note that this semantic is slightly different than the result code for
+ * { link open_async}.
*/
- public abstract async void close_async(Cancellable? cancellable = null) throws Error;
+ public abstract async bool close_async(Cancellable? cancellable = null) throws Error;
/**
- * Wait for the Folder to fully close.
+ * Wait for the { link Folder} to fully close.
*
* Unlike { link wait_for_open_async}, this will ''always'' block until a { link Folder} is
* closed, even if it's not open.
diff --git a/src/engine/app/app-conversation-monitor.vala b/src/engine/app/app-conversation-monitor.vala
index 5baac5c..12ca9d8 100644
--- a/src/engine/app/app-conversation-monitor.vala
+++ b/src/engine/app/app-conversation-monitor.vala
@@ -320,10 +320,13 @@ public class Geary.App.ConversationMonitor : BaseObject {
* supplied to start_monitoring_async() is used during monitoring but *not* for this method.
* If null is supplied as the Cancellable, no cancellable is used; pass the original Cancellable
* here to use that.
+ *
+ * Returns a result code that is semantically identical to the result of
+ * { link Geary.Folder.close_async}.
*/
- public async void stop_monitoring_async(Cancellable? cancellable) throws Error {
+ public async bool stop_monitoring_async(Cancellable? cancellable) throws Error {
if (!is_monitoring)
- return;
+ return false;
yield operation_queue.stop_processing_async(cancellable);
@@ -337,9 +340,10 @@ public class Geary.App.ConversationMonitor : BaseObject {
folder.account.email_flags_changed.disconnect(on_account_email_flags_changed);
folder.account.email_locally_complete.disconnect(on_account_email_locally_complete);
+ bool closing = false;
Error? close_err = null;
try {
- yield folder.close_async(cancellable);
+ closing = yield folder.close_async(cancellable);
} catch (Error err) {
// throw, but only after cleaning up (which is to say, if close_async() fails,
// then the Folder is still treated as closed, which is the best that can be
@@ -353,6 +357,8 @@ public class Geary.App.ConversationMonitor : BaseObject {
if (close_err != null)
throw close_err;
+
+ return closing;
}
/**
diff --git a/src/engine/imap-engine/imap-engine-minimal-folder.vala
b/src/engine/imap-engine/imap-engine-minimal-folder.vala
index c8e460e..9759d9c 100644
--- a/src/engine/imap-engine/imap-engine-minimal-folder.vala
+++ b/src/engine/imap-engine/imap-engine-minimal-folder.vala
@@ -774,25 +774,27 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
notify_opened(Geary.Folder.OpenState.BOTH, remote_count);
}
- public override async void close_async(Cancellable? cancellable = null) throws Error {
+ public override async bool close_async(Cancellable? cancellable = null) throws Error {
// Check open_count but only decrement inside of replay queue
if (open_count <= 0)
- return;
+ return false;
UserClose user_close = new UserClose(this, cancellable);
replay_queue.schedule(user_close);
yield user_close.wait_for_ready_async(cancellable);
+
+ return user_close.closing;
}
public override async void wait_for_close_async(Cancellable? cancellable = null) throws Error {
yield closed_semaphore.wait_async(cancellable);
}
- internal async void user_close_async(Cancellable? cancellable) {
+ internal async bool user_close_async(Cancellable? cancellable) {
// decrement open_count and, if zero, continue closing Folder
if (open_count == 0 || --open_count > 0)
- return;
+ return false;
if (remote_folder != null)
_properties.remove(remote_folder.properties);
@@ -803,6 +805,8 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport
// don't yield here, close_internal_async() needs to be called outside of the replay queue
// the open_count protects against this path scheduling it more than once
close_internal_async.begin(CloseReason.LOCAL_CLOSE, CloseReason.REMOTE_CLOSE, true, cancellable);
+
+ return true;
}
// Close the remote connection and, if open_count is zero, the Folder itself. A Mutex is used
diff --git a/src/engine/imap-engine/replay-ops/imap-engine-user-close.vala
b/src/engine/imap-engine/replay-ops/imap-engine-user-close.vala
index 96474cb..00a53b8 100644
--- a/src/engine/imap-engine/replay-ops/imap-engine-user-close.vala
+++ b/src/engine/imap-engine/replay-ops/imap-engine-user-close.vala
@@ -5,6 +5,8 @@
*/
private class Geary.ImapEngine.UserClose : Geary.ImapEngine.ReplayOperation {
+ public bool closing = false;
+
private MinimalFolder owner;
private Cancellable? cancellable;
@@ -25,7 +27,7 @@ private class Geary.ImapEngine.UserClose : Geary.ImapEngine.ReplayOperation {
}
public override async ReplayOperation.Status replay_local_async() throws Error {
- yield owner.user_close_async(cancellable);
+ closing = yield owner.user_close_async(cancellable);
return ReplayOperation.Status.COMPLETED;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]