[geary] Use new ReetrantProgressMonitor for folder open: Refs bug #730483
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary] Use new ReetrantProgressMonitor for folder open: Refs bug #730483
- Date: Wed, 21 May 2014 19:40:59 +0000 (UTC)
commit 3a157b42cc26e6fbd30ca6b59256f0ec5d3a3995
Author: Jim Nelson <jim yorba org>
Date: Wed May 21 12:39:16 2014 -0700
Use new ReetrantProgressMonitor for folder open: Refs bug #730483
open_remote_async() is reetrant and ProgressMonitor is not, and my
previous attempts to work around this impedence mismatch are obviously
not working. This introduces a reentrant progress monitor for folder
opens only, although it might be useful elsewhere.
src/engine/api/geary-progress-monitor.vala | 46 ++++++++++++++++++++
.../imap-engine/imap-engine-minimal-folder.vala | 5 +-
2 files changed, 48 insertions(+), 3 deletions(-)
---
diff --git a/src/engine/api/geary-progress-monitor.vala b/src/engine/api/geary-progress-monitor.vala
index ee0040d..6ffcbfd 100644
--- a/src/engine/api/geary-progress-monitor.vala
+++ b/src/engine/api/geary-progress-monitor.vala
@@ -69,6 +69,52 @@ public abstract class Geary.ProgressMonitor : BaseObject {
}
/**
+ * A reentrant { link ProgressMonitor}.
+ *
+ * This is not thread-safe; it's designed for single-threaded asynchronous (non-blocking) use.
+ */
+
+public class Geary.ReentrantProgressMonitor : Geary.ProgressMonitor {
+ private int start_count = 0;
+
+ public ReentrantProgressMonitor(ProgressType type) {
+ this.progress_type = type;
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * Unlike the base class implementation, this may be called multiple times successively without
+ * a problem, but each must be matched by a { link notify_finish} to completely stop the
+ * monitor.
+ *
+ * This is not thread-safe; it's designed for single-threaded asynchronous (non-blocking) use.
+ */
+ public override void notify_start() {
+ if (start_count++ == 0)
+ base.notify_start();
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * Unlike the base class implementation, this may be called multiple times successively as
+ * long as they were matched by a prior { link notify_start}.
+ *
+ * This is not thread-safe; it's designed for single-threaded asynchronous (non-blocking) use.
+ */
+ public override void notify_finish() {
+ bool finished = (--start_count == 0);
+
+ // prevent underflow before signalling
+ start_count = start_count.clamp(0, int.MAX);
+
+ if (finished)
+ base.notify_finish();
+ }
+}
+
+/**
* Captures the progress of a single action.
*/
public class Geary.SimpleProgressMonitor : Geary.ProgressMonitor {
diff --git a/src/engine/imap-engine/imap-engine-minimal-folder.vala
b/src/engine/imap-engine/imap-engine-minimal-folder.vala
index f5b7423..94223c6 100644
--- a/src/engine/imap-engine/imap-engine-minimal-folder.vala
+++ b/src/engine/imap-engine/imap-engine-minimal-folder.vala
@@ -55,7 +55,7 @@ private class Geary.ImapEngine.MinimalFolder : Geary.AbstractFolder, Geary.Folde
_special_folder_type = special_folder_type;
_properties.add(local_folder.get_properties());
- opening_monitor = new Geary.SimpleProgressMonitor(Geary.ProgressType.ACTIVITY);
+ opening_monitor = new Geary.ReentrantProgressMonitor(Geary.ProgressType.ACTIVITY);
email_flag_watcher = new EmailFlagWatcher(this);
email_flag_watcher.email_flags_changed.connect(on_email_flags_changed);
@@ -544,8 +544,7 @@ private class Geary.ImapEngine.MinimalFolder : Geary.AbstractFolder, Geary.Folde
// to ensure this isn't running when open_remote_async() is called again (due to a connection
// reestablishment), stop this monitoring from running *before* launching close_internal_async
// ... in essence, guard against reentrancy, which is possible
- if (!opening_monitor.is_in_progress)
- opening_monitor.notify_start();
+ opening_monitor.notify_start();
// following blocks of code are fairly tricky because if the remote open fails need to
// carefully back out and possibly retry
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]