[geary/wip/imap-disconnects-ignored: 15/18] Handle Imap.Deserialiser EOS better



commit b257704c8cab6ad48d548867f21167729ef9c843
Author: Michael Gratton <mike vee net>
Date:   Sat Aug 10 11:29:13 2019 +1000

    Handle Imap.Deserialiser EOS better
    
    Ensure that the client connection is disconnected when the deserialiser
    receives an EOS from its underlying stream. Rename the signal used
    by Imap.ClientConnection to notify the Imap.ClientSession of EOS to make
    it more clear what is going on.
    
    Resolves the issue in #481 where an EOS was recevied but the connection
    was not pulled down until after a NOOP was sent and timed out.

 .../imap/transport/imap-client-connection.vala     | 10 ++---
 src/engine/imap/transport/imap-client-session.vala | 48 ++++++++++++----------
 2 files changed, 31 insertions(+), 27 deletions(-)
---
diff --git a/src/engine/imap/transport/imap-client-connection.vala 
b/src/engine/imap/transport/imap-client-connection.vala
index 960d12aa..fd9e2f1b 100644
--- a/src/engine/imap/transport/imap-client-connection.vala
+++ b/src/engine/imap/transport/imap-client-connection.vala
@@ -1,9 +1,9 @@
 /*
  * Copyright 2016 Software Freedom Conservancy Inc.
- * Copyright 2018 Michael Gratton <mike vee net>
+ * Copyright 2018-2019 Michael Gratton <mike vee net>
  *
  * This software is licensed under the GNU Lesser General Public License
- * (version 2.1 or later).  See the COPYING file in this distribution.
+ * (version 2.1 or later). See the COPYING file in this distribution.
  */
 
 public class Geary.Imap.ClientConnection : BaseObject {
@@ -114,8 +114,8 @@ public class Geary.Imap.ClientConnection : BaseObject {
             root.to_string(), err.message);
     }
 
-    public virtual signal void recv_closed() {
-        Logging.debug(Logging.Flag.NETWORK, "[%s] recv closed", to_string());
+    public virtual signal void received_eos() {
+        Logging.debug(Logging.Flag.NETWORK, "[%s] recv eos", to_string());
     }
 
     public virtual signal void send_failure(Error err) {
@@ -596,7 +596,7 @@ public class Geary.Imap.ClientConnection : BaseObject {
     }
 
     private void on_eos() {
-        recv_closed();
+        received_eos();
     }
 
     private void on_command_timeout(Command command) {
diff --git a/src/engine/imap/transport/imap-client-session.vala 
b/src/engine/imap/transport/imap-client-session.vala
index 93ef9f33..07ed573f 100644
--- a/src/engine/imap/transport/imap-client-session.vala
+++ b/src/engine/imap/transport/imap-client-session.vala
@@ -750,7 +750,7 @@ public class Geary.Imap.ClientSession : BaseObject {
         cx.received_continuation_response.connect(on_received_continuation_response);
         cx.received_bytes.connect(on_received_bytes);
         cx.received_bad_response.connect(on_received_bad_response);
-        cx.recv_closed.connect(on_received_closed);
+        cx.received_eos.connect(on_received_eos);
         cx.receive_failure.connect(on_network_receive_failure);
         cx.deserialize_failure.connect(on_network_receive_failure);
 
@@ -777,7 +777,7 @@ public class Geary.Imap.ClientSession : BaseObject {
             cx.received_continuation_response.disconnect(on_received_continuation_response);
             cx.received_bytes.disconnect(on_received_bytes);
             cx.received_bad_response.disconnect(on_received_bad_response);
-            cx.recv_closed.disconnect(on_received_closed);
+            cx.received_eos.connect(on_received_eos);
             cx.receive_failure.disconnect(on_network_receive_failure);
             cx.deserialize_failure.disconnect(on_network_receive_failure);
 
@@ -1606,16 +1606,20 @@ public class Geary.Imap.ClientSession : BaseObject {
     // error handling
     //
 
-    // use different error handler when connecting because, if connect_async() fails, there's no
-    // requirement for the user to call disconnect_async() and clean up... this prevents leaving the
-    //  FSM in the CONNECTING state, causing an assertion when this object is destroyed
-    private uint on_connecting_send_recv_error(uint state, uint event, void *user, Object? object, Error? 
err) {
-        assert(err != null);
-
-        debug("[%s] Connecting send/recv error, dropping client connection: %s", to_string(), err.message);
-
+    // use different error handler when connecting because, if
+    // connect_async() fails, there's no requirement for the user to
+    // call disconnect_async() and clean up... this prevents leaving
+    // the FSM in the CONNECTING state, causing an assertion when this
+    // object is destroyed
+    private uint on_connecting_send_recv_error(uint state,
+                                               uint event,
+                                               void *user,
+                                               GLib.Object? object,
+                                               GLib.Error? err) {
+        debug("[%s] Connecting send/recv error, dropping client connection: %s",
+              to_string(),
+              err != null ? err.message : "EOS");
         fsm.do_post_transition(() => { drop_connection(); });
-
         return State.BROKEN;
     }
 
@@ -1636,12 +1640,16 @@ public class Geary.Imap.ClientSession : BaseObject {
         dispatch_disconnect_results(DisconnectReason.LOCAL_ERROR, result);
     }
 
-    private uint on_recv_error(uint state, uint event, void *user, Object? object, Error? err) {
-        assert(err != null);
-        debug("[%s] Receive error, disconnecting: %s", to_string(), err.message);
-
+    private uint on_recv_error(uint state,
+                               uint event,
+                               void *user,
+                               GLib.Object? object,
+                               GLib.Error? err) {
+        debug("[%s] Receive error, disconnecting: %s",
+              to_string(),
+              (err != null) ? err.message : "EOS"
+        );
         cx.disconnect_async.begin(null, on_fire_recv_error_signal);
-
         return State.BROKEN;
     }
 
@@ -1906,12 +1914,8 @@ public class Geary.Imap.ClientSession : BaseObject {
         debug("[%s] Received bad response %s: %s", to_string(), root.to_string(), err.message);
     }
 
-    private void on_received_closed(ClientConnection cx) {
-#if VERBOSE_SESSION
-        // This currently doesn't generate any Events, but it does mean the connection has closed
-        // due to EOS
-        debug("[%s] Received closed", to_string());
-#endif
+    private void on_received_eos(ClientConnection cx) {
+        fsm.issue(Event.RECV_ERROR, null, null, null);
     }
 
     private void on_network_receive_failure(Error err) {


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