[geary] Update ClientConnection state machine inside mutex



commit eb1b9971d6134485e10f96b0f4ce3b54e126ad35
Author: Jim Nelson <jim yorba org>
Date:   Wed Aug 13 18:07:28 2014 -0700

    Update ClientConnection state machine inside mutex
    
    While looking at a user's network log I spotted a server error related
    to how Geary drops from the IMAP connection's IDLE state.  There was a
    timing hole where a command could be issued while a flush followed by
    an IDLE was issued.  Without updating the FSM, the new command would
    be queued without issuing a DONE to end IDLE.

 .../imap/transport/imap-client-connection.vala     |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)
---
diff --git a/src/engine/imap/transport/imap-client-connection.vala 
b/src/engine/imap/transport/imap-client-connection.vala
index e6dfce7..d4dd7b7 100644
--- a/src/engine/imap/transport/imap-client-connection.vala
+++ b/src/engine/imap/transport/imap-client-connection.vala
@@ -557,17 +557,20 @@ public class Geary.Imap.ClientConnection : BaseObject {
     public async void send_async(Command cmd, Cancellable? cancellable = null) throws Error {
         check_for_connection();
         
+        // need to run this in critical section because Serializer requires it (don't want to be
+        // pushing data while a flush_async() is occurring)
+        int token = yield send_mutex.claim_async(cancellable);
+        
+        // This needs to happen inside mutex because flush async also manipulates FSM
         if (!issue_conditional_event(Event.SEND)) {
             debug("[%s] Send async not allowed", to_string());
             
+            send_mutex.release(ref token);
+            
             throw new ImapError.NOT_CONNECTED("Send not allowed: connection in %s state",
                 fsm.get_state_string(fsm.get_state()));
         }
         
-        // need to run this in critical section because Serializer requires it (don't want to be
-        // pushing data while a flush_async() is occurring)
-        int token = yield send_mutex.claim_async(cancellable);
-        
         // Always assign a new tag; Commands with pre-assigned Tags should not be re-sent.
         // (Do this inside the critical section to ensure commands go out in Tag order; this is not
         // an IMAP requirement but makes tracing commands easier.)


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