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);
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,
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
};
(*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);
};
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;
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
};
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;
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);