dovecot-2.0: dsync: Fixed assert-crashing when messages couldn't...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Jul 10 17:57:41 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/56cf4f6261dd
changeset: 11771:56cf4f6261dd
user: Timo Sirainen <tss at iki.fi>
date: Sat Jul 10 15:56:45 2010 +0100
description:
dsync: Fixed assert-crashing when messages couldn't be sent fast enough to remote
diffstat:
src/dsync/dsync-brain-msgs-new.c | 24 ++++++++++++++++++------
src/dsync/dsync-proxy-client.c | 14 +++++++++++++-
src/dsync/dsync-proxy-server-cmd.c | 12 +++++++++++-
src/dsync/dsync-proxy-server.h | 1 +
src/dsync/dsync-worker-local.c | 14 +++++++++++++-
src/dsync/dsync-worker-private.h | 4 +++-
src/dsync/dsync-worker.c | 8 ++++++--
src/dsync/dsync-worker.h | 9 ++++++---
src/dsync/test-dsync-worker.c | 6 +++++-
9 files changed, 76 insertions(+), 16 deletions(-)
diffs (truncated from 308 to 300 lines):
diff -r 02447bd723e8 -r 56cf4f6261dd src/dsync/dsync-brain-msgs-new.c
--- a/src/dsync/dsync-brain-msgs-new.c Fri Jul 09 22:33:05 2010 +0100
+++ b/src/dsync/dsync-brain-msgs-new.c Sat Jul 10 15:56:45 2010 +0100
@@ -48,6 +48,15 @@
static void
dsync_brain_msg_sync_add_new_msgs(struct dsync_brain_msg_iter *iter);
+static void msg_save_callback(void *context)
+{
+ struct dsync_brain_msg_save_context *ctx = context;
+
+ if (--ctx->iter->save_results_left == 0 && !ctx->iter->adding_msgs)
+ dsync_brain_msg_sync_add_new_msgs(ctx->iter);
+ i_free(ctx);
+}
+
static void msg_get_callback(enum dsync_msg_get_result result,
const struct dsync_msg_static_data *data,
void *context)
@@ -56,6 +65,8 @@
const struct dsync_brain_mailbox *mailbox;
struct istream *input;
+ i_assert(ctx->iter->save_results_left > 0);
+
mailbox = array_idx(&ctx->iter->sync->mailboxes, ctx->mailbox_idx);
switch (result) {
case DSYNC_MSG_GET_RESULT_SUCCESS:
@@ -64,21 +75,21 @@
dsync_worker_select_mailbox(ctx->iter->worker, &mailbox->box);
input = data->input;
- dsync_worker_msg_save(ctx->iter->worker, ctx->msg, data);
+ dsync_worker_msg_save(ctx->iter->worker, ctx->msg, data,
+ msg_save_callback, ctx);
i_stream_unref(&input);
break;
case DSYNC_MSG_GET_RESULT_EXPUNGED:
/* mail got expunged during sync. just skip this. */
+ msg_save_callback(ctx);
break;
case DSYNC_MSG_GET_RESULT_FAILED:
i_error("msg-get failed: box=%s uid=%u guid=%s",
mailbox->box.name, ctx->msg->uid, ctx->msg->guid);
dsync_brain_fail(ctx->iter->sync->brain);
+ msg_save_callback(ctx);
break;
}
- if (--ctx->iter->save_results_left == 0 && !ctx->iter->adding_msgs)
- dsync_brain_msg_sync_add_new_msgs(ctx->iter);
- i_free(ctx);
}
static void
@@ -297,8 +308,9 @@
/* all messages saved for this mailbox. continue with saving
its conflicts and waiting for copies to finish. */
dsync_brain_mailbox_save_conflicts(iter);
- if (iter->copy_results_left > 0) {
- /* wait for copies to finish */
+ if (iter->save_results_left > 0 ||
+ iter->copy_results_left > 0) {
+ /* wait for saves/copies to finish */
return;
}
diff -r 02447bd723e8 -r 56cf4f6261dd src/dsync/dsync-proxy-client.c
--- a/src/dsync/dsync-proxy-client.c Fri Jul 09 22:33:05 2010 +0100
+++ b/src/dsync/dsync-proxy-client.c Sat Jul 10 15:56:45 2010 +0100
@@ -56,6 +56,8 @@
mailbox_guid_t selected_box_guid;
+ dsync_worker_save_callback_t *save_callback;
+ void *save_context;
struct istream *save_input;
struct io *save_io;
bool save_input_last_lf;
@@ -907,6 +909,7 @@
static void proxy_client_send_stream(struct proxy_client_dsync_worker *worker)
{
+ dsync_worker_save_callback_t *callback;
const unsigned char *data;
size_t size;
int ret;
@@ -947,13 +950,20 @@
i_assert(!i_stream_have_bytes_left(worker->save_input));
o_stream_send(worker->output, "\n.\n", 3);
}
+
+ callback = worker->save_callback;
+ worker->save_callback = NULL;
i_stream_unref(&worker->save_input);
+
+ callback(worker->save_context);
}
static void
proxy_client_worker_msg_save(struct dsync_worker *_worker,
const struct dsync_message *msg,
- const struct dsync_msg_static_data *data)
+ const struct dsync_msg_static_data *data,
+ dsync_worker_save_callback_t *callback,
+ void *context)
{
struct proxy_client_dsync_worker *worker =
(struct proxy_client_dsync_worker *)_worker;
@@ -972,6 +982,8 @@
} T_END;
i_assert(worker->save_io == NULL);
+ worker->save_callback = callback;
+ worker->save_context = context;
worker->save_input = data->input;
worker->save_input_last_lf = TRUE;
i_stream_ref(worker->save_input);
diff -r 02447bd723e8 -r 56cf4f6261dd src/dsync/dsync-proxy-server-cmd.c
--- a/src/dsync/dsync-proxy-server-cmd.c Fri Jul 09 22:33:05 2010 +0100
+++ b/src/dsync/dsync-proxy-server-cmd.c Sat Jul 10 15:56:45 2010 +0100
@@ -415,6 +415,13 @@
return 1;
}
+static void cmd_msg_save_callback(void *context)
+{
+ struct dsync_proxy_server *server = context;
+
+ server->save_finished = TRUE;
+}
+
static int
cmd_msg_save(struct dsync_proxy_server *server, const char *const *args)
{
@@ -437,10 +444,13 @@
}
/* we rely on save reading the entire input */
+ server->save_finished = FALSE;
net_set_nonblock(server->fd_in, FALSE);
- dsync_worker_msg_save(server->worker, &msg, &data);
+ dsync_worker_msg_save(server->worker, &msg, &data,
+ cmd_msg_save_callback, server);
net_set_nonblock(server->fd_in, TRUE);
ret = dsync_worker_has_failed(server->worker) ? -1 : 1;
+ i_assert(server->save_finished);
i_assert(data.input->eof || ret < 0);
i_stream_destroy(&data.input);
return ret;
diff -r 02447bd723e8 -r 56cf4f6261dd src/dsync/dsync-proxy-server.h
--- a/src/dsync/dsync-proxy-server.h Fri Jul 09 22:33:05 2010 +0100
+++ b/src/dsync/dsync-proxy-server.h Sat Jul 10 15:56:45 2010 +0100
@@ -32,6 +32,7 @@
unsigned int handshake_received:1;
unsigned int subs_sending_unsubscriptions:1;
+ unsigned int save_finished:1;
unsigned int finished:1;
};
diff -r 02447bd723e8 -r 56cf4f6261dd src/dsync/dsync-worker-local.c
--- a/src/dsync/dsync-worker-local.c Fri Jul 09 22:33:05 2010 +0100
+++ b/src/dsync/dsync-worker-local.c Sat Jul 10 15:56:45 2010 +0100
@@ -95,6 +95,8 @@
struct io *save_io;
struct mail_save_context *save_ctx;
struct istream *save_input;
+ dsync_worker_save_callback_t *save_callback;
+ void *save_context;
dsync_worker_finish_callback_t *finish_callback;
void *finish_context;
@@ -1516,6 +1518,7 @@
local_worker_save_msg_continue(struct local_dsync_worker *worker)
{
struct mailbox *dest_box = worker->ext_mail->box;
+ dsync_worker_save_callback_t *callback;
int ret;
while ((ret = i_stream_read(worker->save_input)) > 0) {
@@ -1552,14 +1555,20 @@
mail_storage_get_last_error(storage, NULL));
dsync_worker_set_failure(&worker->worker);
}
+ callback = worker->save_callback;
+ worker->save_callback = NULL;
i_stream_unref(&worker->save_input);
+
+ callback(worker->save_context);
dsync_worker_try_finish(worker);
}
static void
local_worker_msg_save(struct dsync_worker *_worker,
const struct dsync_message *msg,
- const struct dsync_msg_static_data *data)
+ const struct dsync_msg_static_data *data,
+ dsync_worker_save_callback_t *callback,
+ void *context)
{
struct local_dsync_worker *worker =
(struct local_dsync_worker *)_worker;
@@ -1582,9 +1591,12 @@
mailbox_get_vname(dest_box),
mail_storage_get_last_error(storage, NULL));
dsync_worker_set_failure(_worker);
+ callback(context);
return;
}
+ worker->save_callback = callback;
+ worker->save_context = context;
worker->save_input = data->input;
worker->save_ctx = save_ctx;
i_stream_ref(worker->save_input);
diff -r 02447bd723e8 -r 56cf4f6261dd src/dsync/dsync-worker-private.h
--- a/src/dsync/dsync-worker-private.h Fri Jul 09 22:33:05 2010 +0100
+++ b/src/dsync/dsync-worker-private.h Sat Jul 10 15:56:45 2010 +0100
@@ -62,7 +62,9 @@
dsync_worker_copy_callback_t *callback, void *context);
void (*msg_save)(struct dsync_worker *worker,
const struct dsync_message *msg,
- const struct dsync_msg_static_data *data);
+ const struct dsync_msg_static_data *data,
+ dsync_worker_save_callback_t *callback,
+ void *context);
void (*msg_save_cancel)(struct dsync_worker *worker);
void (*msg_get)(struct dsync_worker *worker,
const mailbox_guid_t *mailbox, uint32_t uid,
diff -r 02447bd723e8 -r 56cf4f6261dd src/dsync/dsync-worker.c
--- a/src/dsync/dsync-worker.c Fri Jul 09 22:33:05 2010 +0100
+++ b/src/dsync/dsync-worker.c Sat Jul 10 15:56:45 2010 +0100
@@ -222,11 +222,14 @@
void dsync_worker_msg_save(struct dsync_worker *worker,
const struct dsync_message *msg,
- const struct dsync_msg_static_data *data)
+ const struct dsync_msg_static_data *data,
+ dsync_worker_save_callback_t *callback,
+ void *context)
{
if (!worker->readonly) {
if (!worker->failed) T_BEGIN {
- worker->v.msg_save(worker, msg, data);
+ worker->v.msg_save(worker, msg, data,
+ callback, context);
} T_END;
} else {
const unsigned char *d;
@@ -234,6 +237,7 @@
while ((i_stream_read_data(data->input, &d, &size, 0)) > 0)
i_stream_skip(data->input, size);
+ callback(context);
}
}
diff -r 02447bd723e8 -r 56cf4f6261dd src/dsync/dsync-worker.h
--- a/src/dsync/dsync-worker.h Fri Jul 09 22:33:05 2010 +0100
+++ b/src/dsync/dsync-worker.h Sat Jul 10 15:56:45 2010 +0100
@@ -23,6 +23,7 @@
};
typedef void dsync_worker_copy_callback_t(bool success, void *context);
+typedef void dsync_worker_save_callback_t(void *context);
typedef void dsync_worker_msg_callback_t(enum dsync_msg_get_result result,
const struct dsync_msg_static_data *data,
void *context);
@@ -133,11 +134,13 @@
const struct dsync_message *dest_msg,
dsync_worker_copy_callback_t *callback,
void *context);
-/* Save given message from the given input stream. The stream is destroyed once
- saving is finished. */
+/* Save given message from the given input stream. Once saving is finished,
+ the given callback is called and the stream is destroyed. */
void dsync_worker_msg_save(struct dsync_worker *worker,
const struct dsync_message *msg,
- const struct dsync_msg_static_data *data);
+ const struct dsync_msg_static_data *data,
+ dsync_worker_save_callback_t *callback,
+ void *context);
/* Cancel any pending saves */
void dsync_worker_msg_save_cancel(struct dsync_worker *worker);
/* Get message data for saving. The callback is called once when the static
diff -r 02447bd723e8 -r 56cf4f6261dd src/dsync/test-dsync-worker.c
--- a/src/dsync/test-dsync-worker.c Fri Jul 09 22:33:05 2010 +0100
+++ b/src/dsync/test-dsync-worker.c Sat Jul 10 15:56:45 2010 +0100
@@ -388,7 +388,9 @@
static void
test_worker_msg_save(struct dsync_worker *_worker,
const struct dsync_message *msg,
- const struct dsync_msg_static_data *data)
+ const struct dsync_msg_static_data *data,
+ dsync_worker_save_callback_t *callback,
+ void *context)
{
struct test_dsync_worker *worker = (struct test_dsync_worker *)_worker;
struct test_dsync_msg_event *event;
@@ -408,6 +410,8 @@
More information about the dovecot-cvs
mailing list