]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dsync: Close mail streams earlier on failures to avoid assert-crashing
authorTimo Sirainen <tss@iki.fi>
Thu, 10 Jan 2013 10:12:50 +0000 (12:12 +0200)
committerTimo Sirainen <tss@iki.fi>
Thu, 10 Jan 2013 10:12:50 +0000 (12:12 +0200)
src/doveadm/dsync/dsync-brain.c
src/doveadm/dsync/dsync-ibc-pipe.c
src/doveadm/dsync/dsync-ibc-private.h
src/doveadm/dsync/dsync-ibc-stream.c
src/doveadm/dsync/dsync-ibc.c
src/doveadm/dsync/dsync-ibc.h

index fa342773ed1f16f44aab586bc90477bfeb3468be..bbdeb25f71628dc7acb6a886fbad06fc4a90bd12 100644 (file)
@@ -158,6 +158,7 @@ int dsync_brain_deinit(struct dsync_brain **_brain)
        if (dsync_ibc_has_failed(brain->ibc) ||
            brain->state != DSYNC_STATE_DONE)
                brain->failed = TRUE;
+       dsync_ibc_close_mail_streams(brain->ibc);
 
        if (brain->box != NULL)
                dsync_brain_sync_mailbox_deinit(brain);
index 21a966baedbfb5af66b2a8633e1c396b45e93e11..f7a6b313817f94911f0186d9be284a36be821d55 100644 (file)
@@ -434,6 +434,26 @@ dsync_ibc_pipe_recv_mail(struct dsync_ibc *ibc, struct dsync_mail **mail_r)
        return DSYNC_IBC_RECV_RET_OK;
 }
 
+static void pipe_close_mail_streams(struct dsync_ibc_pipe *pipe)
+{
+       struct item *item;
+
+       if (array_count(&pipe->item_queue) > 0) {
+               item = array_idx_modifiable(&pipe->item_queue, 0);
+               if (item->type == ITEM_MAIL &&
+                   item->u.mail.input != NULL)
+                       i_stream_unref(&item->u.mail.input);
+       }
+}
+
+static void dsync_ibc_pipe_close_mail_streams(struct dsync_ibc *ibc)
+{
+       struct dsync_ibc_pipe *pipe = (struct dsync_ibc_pipe *)ibc;
+
+       pipe_close_mail_streams(pipe);
+       pipe_close_mail_streams(pipe->remote);
+}
+
 static const struct dsync_ibc_vfuncs dsync_ibc_pipe_vfuncs = {
        dsync_ibc_pipe_deinit,
        dsync_ibc_pipe_send_handshake,
@@ -453,6 +473,7 @@ static const struct dsync_ibc_vfuncs dsync_ibc_pipe_vfuncs = {
        dsync_ibc_pipe_recv_mail_request,
        dsync_ibc_pipe_send_mail,
        dsync_ibc_pipe_recv_mail,
+       dsync_ibc_pipe_close_mail_streams,
        dsync_ibc_pipe_is_send_queue_full,
        dsync_ibc_pipe_has_pending_data
 };
index 09ccea4db9babdec140426673a9bd089eb4bcf14..0871f06d048a79bf297b28fc817cc529c8fcb0bc 100644 (file)
@@ -61,6 +61,7 @@ struct dsync_ibc_vfuncs {
                (*recv_mail)(struct dsync_ibc *ibc,
                             struct dsync_mail **mail_r);
 
+       void (*close_mail_streams)(struct dsync_ibc *ibc);
        bool (*is_send_queue_full)(struct dsync_ibc *ibc);
        bool (*has_pending_data)(struct dsync_ibc *ibc);
 };
index d1b45588df2030cd411b889a5e4c0ce72849b0a8..68fdcfebe815c342bdd140042a48d8c5c1ac4e40 100644 (file)
@@ -1489,6 +1489,16 @@ dsync_ibc_stream_recv_mail(struct dsync_ibc *_ibc, struct dsync_mail **mail_r)
        return DSYNC_IBC_RECV_RET_OK;
 }
 
+static void dsync_ibc_stream_close_mail_streams(struct dsync_ibc *_ibc)
+{
+       struct dsync_ibc_stream *ibc = (struct dsync_ibc_stream *)_ibc;
+
+       if (ibc->mail_output != NULL) {
+               i_stream_unref(&ibc->mail_output);
+               dsync_ibc_stream_stop(ibc);
+       }
+}
+
 static bool dsync_ibc_stream_is_send_queue_full(struct dsync_ibc *_ibc)
 {
        struct dsync_ibc_stream *ibc = (struct dsync_ibc_stream *)_ibc;
@@ -1531,6 +1541,7 @@ static const struct dsync_ibc_vfuncs dsync_ibc_stream_vfuncs = {
        dsync_ibc_stream_recv_mail_request,
        dsync_ibc_stream_send_mail,
        dsync_ibc_stream_recv_mail,
+       dsync_ibc_stream_close_mail_streams,
        dsync_ibc_stream_is_send_queue_full,
        dsync_ibc_stream_has_pending_data
 };
index 7db6322f05a1d1923fc481c611773d6d8f050534..faba4ca1e60bcfadfe3fcbcd73b4c72056f214e1 100644 (file)
@@ -178,6 +178,11 @@ dsync_ibc_recv_mail(struct dsync_ibc *ibc, struct dsync_mail **mail_r)
        return ibc->v.recv_mail(ibc, mail_r);
 }
 
+void dsync_ibc_close_mail_streams(struct dsync_ibc *ibc)
+{
+       ibc->v.close_mail_streams(ibc);
+}
+
 bool dsync_ibc_has_failed(struct dsync_ibc *ibc)
 {
        return ibc->failed;
index 7d9ecd2b591b52f7d5d64bd12a4b579f9685c895..8ab753e552db19b0ccf16859f80e67ca25a667cb 100644 (file)
@@ -110,6 +110,10 @@ dsync_ibc_send_mail(struct dsync_ibc *ibc, const struct dsync_mail *mail);
 enum dsync_ibc_recv_ret
 dsync_ibc_recv_mail(struct dsync_ibc *ibc, struct dsync_mail **mail_r);
 
+/* Close any mail input streams that are kept open. This needs to be called
+   before the mail is attempted to be freed (usually on error conditions). */
+void dsync_ibc_close_mail_streams(struct dsync_ibc *ibc);
+
 bool dsync_ibc_has_failed(struct dsync_ibc *ibc);
 bool dsync_ibc_is_send_queue_full(struct dsync_ibc *ibc);
 bool dsync_ibc_has_pending_data(struct dsync_ibc *ibc);