]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imapc: Try to avoid crashes on deinit/disconnection.
authorTimo Sirainen <tss@iki.fi>
Wed, 14 Dec 2011 12:29:07 +0000 (14:29 +0200)
committerTimo Sirainen <tss@iki.fi>
Wed, 14 Dec 2011 12:29:07 +0000 (14:29 +0200)
src/lib-imap-client/imapc-client-private.h
src/lib-imap-client/imapc-client.c
src/lib-imap-client/imapc-connection.c

index 70c54b2a0c5bb42fe96289308acb617599189c7c..c940cfdd90d28f8b96ae0868d78877b0d3645535 100644 (file)
@@ -36,6 +36,7 @@ struct imapc_client_mailbox {
 
        bool reconnect_ok;
        bool reconnecting;
+       bool closing;
 };
 
 void imapc_client_ref(struct imapc_client *client);
index 1eaa0cf0c17a11bec3ede69fdbb3a2d1e350dbce..d4321e35cba9406eb4d4ffae855e291047d7f0aa 100644 (file)
@@ -107,6 +107,7 @@ void imapc_client_deinit(struct imapc_client **_client)
        struct imapc_client_connection **connp;
 
        array_foreach_modifiable(&client->conns, connp) {
+               i_assert(imapc_connection_get_mailbox((*connp)->conn) == NULL);
                imapc_connection_deinit(&(*connp)->conn);
                i_free(*connp);
        }
@@ -294,6 +295,8 @@ void imapc_client_mailbox_close(struct imapc_client_mailbox **_box)
        struct imapc_client_mailbox *box = *_box;
        struct imapc_client_connection *const *connp;
 
+       box->closing = TRUE;
+
        /* cancel any pending commands */
        imapc_connection_unselect(box);
 
@@ -324,6 +327,8 @@ imapc_client_mailbox_cmd(struct imapc_client_mailbox *box,
 {
        struct imapc_command *cmd;
 
+       i_assert(!box->closing);
+
        cmd = imapc_connection_cmd(box->conn, callback, context);
        imapc_command_set_mailbox(cmd, box);
        return cmd;
@@ -346,7 +351,8 @@ bool imapc_client_mailbox_is_opened(struct imapc_client_mailbox *box)
 {
        struct imapc_client_mailbox *selected_box;
 
-       if (imapc_connection_get_state(box->conn) != IMAPC_CONNECTION_STATE_DONE)
+       if (box->closing ||
+           imapc_connection_get_state(box->conn) != IMAPC_CONNECTION_STATE_DONE)
                return FALSE;
 
        selected_box = imapc_connection_get_mailbox(box->conn);
index ff7dea43f3e305a49614c8de2fdc3345ea02f391..d2066f69fa8355319add1c53d91b9825168d7b09 100644 (file)
@@ -365,14 +365,14 @@ void imapc_connection_disconnect(struct imapc_connection *conn)
        net_disconnect(conn->fd);
        conn->fd = -1;
 
-       imapc_connection_abort_commands(conn, TRUE, reconnecting);
        imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED);
+       imapc_connection_abort_commands(conn, TRUE, reconnecting);
 }
 
 static void imapc_connection_set_disconnected(struct imapc_connection *conn)
 {
-       imapc_connection_abort_commands(conn, TRUE, FALSE);
        imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED);
+       imapc_connection_abort_commands(conn, TRUE, FALSE);
 }
 
 static void imapc_connection_reconnect(struct imapc_connection *conn)
@@ -1819,9 +1819,6 @@ void imapc_connection_unselect(struct imapc_client_mailbox *box)
 {
        struct imapc_connection *conn = box->conn;
 
-       imapc_connection_send_idle_done(conn);
-       imapc_connection_abort_commands(conn, FALSE, FALSE);
-
        if (conn->selected_box != NULL || conn->selecting_box != NULL) {
                i_assert(conn->selected_box == box ||
                         conn->selecting_box == box);
@@ -1829,6 +1826,8 @@ void imapc_connection_unselect(struct imapc_client_mailbox *box)
                conn->selected_box = NULL;
                conn->selecting_box = NULL;
        }
+       imapc_connection_send_idle_done(conn);
+       imapc_connection_abort_commands(conn, FALSE, FALSE);
 }
 
 struct imapc_client_mailbox *