[geary/wip/721828-undo-2] Some issues with refs and Timeout in the event loop



commit 1363c25737985889fcddf8726da0e2f2469842bc
Author: Jim Nelson <jim yorba org>
Date:   Thu Feb 5 17:48:16 2015 -0800

    Some issues with refs and Timeout in the event loop

 src/client/application/geary-controller.vala       |    6 ++--
 src/engine/api/geary-revokable.vala                |   33 ++++++++++++++++---
 .../imap-engine/imap-engine-revokable-move.vala    |    2 +-
 3 files changed, 31 insertions(+), 10 deletions(-)
---
diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala
index 6424790..e9f24ea 100644
--- a/src/client/application/geary-controller.vala
+++ b/src/client/application/geary-controller.vala
@@ -2518,11 +2518,13 @@ public class GearyController : Geary.BaseObject {
     }
     
     private void save_revokable(Geary.Revokable? new_revokable, string? description) {
-        // disconnect old revokable
+        // disconnect old revokable & blindly commit it
         if (revokable != null) {
             revokable.notify[Geary.Revokable.PROP_VALID].disconnect(on_revokable_valid_changed);
             revokable.notify[Geary.Revokable.PROP_IN_PROCESS].disconnect(update_revokable_action);
             revokable.committed.disconnect(on_revokable_committed);
+            
+            revokable.commit_async.begin();
         }
         
         // store new revokable
@@ -2556,8 +2558,6 @@ public class GearyController : Geary.BaseObject {
         if (committed_revokable == null)
             return;
         
-        debug("Committed Revokable issued another Revokable");
-        
         // use existing description
         Gtk.Action undo_action = GearyApplication.instance.get_action(ACTION_UNDO);
         save_revokable(committed_revokable, undo_action.tooltip);
diff --git a/src/engine/api/geary-revokable.vala b/src/engine/api/geary-revokable.vala
index c6bf35d..ccee2db 100644
--- a/src/engine/api/geary-revokable.vala
+++ b/src/engine/api/geary-revokable.vala
@@ -5,8 +5,12 @@
  */
 
 /**
- * A representation of an operation with the Geary Engine that make be revoked (undone) at a later
+ * A representation of an operation with the Geary Engine that may be revoked (undone) at a later
  * time.
+ *
+ * The Revokable will do everything it can to commit the operation (if necessary) when its final
+ * ref is dropped.  However, since the final ref can be dropped at an indeterminate time, it's
+ * advised that callers force the matter by scheduling it with { link commit_async}.
  */
 
 public abstract class Geary.Revokable : BaseObject {
@@ -57,13 +61,22 @@ public abstract class Geary.Revokable : BaseObject {
      * after the timeout expires if it is still { link valid}.
      */
     protected Revokable(int commit_timeout_sec = 0) {
-        if (commit_timeout_sec > 0)
-            commit_timeout_id = Timeout.add_seconds(commit_timeout_sec, on_commit);
+        if (commit_timeout_sec == 0)
+            return;
+        
+        // This holds a reference to the Revokable, meaning cancelling the timeout in the dtor is
+        // largely symbolic, but so be it
+        commit_timeout_id = Timeout.add_seconds(commit_timeout_sec, on_timed_commit);
+        
+        // various events that cancel the need for a timed commit; this is important to drop the
+        // ref to this object within the event loop
+        revoked.connect(cancel_timed_commit);
+        committed.connect(cancel_timed_commit);
+        notify[PROP_VALID].connect(cancel_timed_commit);
     }
     
     ~Revokable() {
-        if (commit_timeout_id > 0)
-            Source.remove(commit_timeout_id);
+        cancel_timed_commit();
     }
     
     protected virtual void notify_revoked() {
@@ -150,7 +163,7 @@ public abstract class Geary.Revokable : BaseObject {
      */
     protected abstract async void internal_commit_async(Cancellable? cancellable) throws Error;
     
-    private bool on_commit() {
+    private bool on_timed_commit() {
         commit_timeout_id = 0;
         
         if (valid && !in_process)
@@ -158,5 +171,13 @@ public abstract class Geary.Revokable : BaseObject {
         
         return false;
     }
+    
+    private void cancel_timed_commit() {
+        if (commit_timeout_id == 0)
+            return;
+        
+        Source.remove(commit_timeout_id);
+        commit_timeout_id = 0;
+    }
 }
 
diff --git a/src/engine/imap-engine/imap-engine-revokable-move.vala 
b/src/engine/imap-engine/imap-engine-revokable-move.vala
index edcef32..cb7f9f8 100644
--- a/src/engine/imap-engine/imap-engine-revokable-move.vala
+++ b/src/engine/imap-engine/imap-engine-revokable-move.vala
@@ -43,7 +43,7 @@ private class Geary.ImapEngine.RevokableMove : Revokable {
         source.closing.disconnect(on_source_closing);
         
         // if still valid, schedule operation so its executed
-        if (valid) {
+        if (valid && source.get_open_state() != Folder.OpenState.CLOSED) {
             debug("Freeing revokable, scheduling move %d emails from %s to %s", move_ids.size,
                 source.path.to_string(), destination.to_string());
             


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]