From: Timo Sirainen Date: Mon, 25 Oct 2010 17:53:04 +0000 (+0100) Subject: dsync: Error handling fixes. X-Git-Tag: 2.0.7~48 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=afe62291feae9ce331e22831d2df16dd8586e652;p=thirdparty%2Fdovecot%2Fcore.git dsync: Error handling fixes. --- diff --git a/src/dsync/dsync-proxy-client.c b/src/dsync/dsync-proxy-client.c index 9da39e7ab4..f676bfd641 100644 --- a/src/dsync/dsync-proxy-client.c +++ b/src/dsync/dsync-proxy-client.c @@ -123,23 +123,12 @@ proxy_client_worker_read_line(struct proxy_client_dsync_worker *worker, } static void -proxy_client_worker_msg_get_done(struct proxy_client_dsync_worker *worker) +proxy_client_worker_msg_get_finish(struct proxy_client_dsync_worker *worker) { - struct istream *input = worker->msg_get_data.input; - const unsigned char *data; - size_t size; - - i_assert(worker->io == NULL); - worker->msg_get_data.input = NULL; worker->io = io_add(worker->fd_in, IO_READ, proxy_client_worker_input, worker); - /* we'll need to read the input until EOF or we'll start treating the - input as commands. make sure saving read everything. */ - while ((i_stream_read_data(input, &data, &size, 0)) > 0) - i_stream_skip(input, size); - /* some input may already be buffered. note that we may be coming here from the input function itself, in which case this timeout must not be called (we'll remove it later) */ @@ -149,6 +138,43 @@ proxy_client_worker_msg_get_done(struct proxy_client_dsync_worker *worker) } } +static void +proxy_client_worker_read_to_eof(struct proxy_client_dsync_worker *worker) +{ + struct istream *input = worker->msg_get_data.input; + const unsigned char *data; + size_t size; + int ret; + + while ((ret = i_stream_read_data(input, &data, &size, 0)) > 0) + i_stream_skip(input, size); + if (ret == -1) { + i_stream_unref(&input); + io_remove(&worker->io); + proxy_client_worker_msg_get_finish(worker); + } +} + +static void +proxy_client_worker_msg_get_done(struct proxy_client_dsync_worker *worker) +{ + struct istream *input = worker->msg_get_data.input; + + i_assert(worker->io == NULL); + + if (input->eof) + proxy_client_worker_msg_get_finish(worker); + else { + /* saving read the message only partially. we'll need to read + the input until EOF or we'll start treating the input as + commands. */ + worker->io = io_add(worker->fd_in, IO_READ, + proxy_client_worker_read_to_eof, worker); + worker->msg_get_data.input = + i_stream_create_dot(worker->input, FALSE); + } +} + static bool proxy_client_worker_next_copy(struct proxy_client_dsync_worker *worker, const struct proxy_client_request *request, @@ -232,7 +258,7 @@ proxy_client_worker_next_msg_get(struct proxy_client_dsync_worker *worker, } request->callback.get(result, &worker->msg_get_data, request->context); - return worker->io != NULL; + return worker->io != NULL && worker->msg_get_data.input == NULL; } static void diff --git a/src/dsync/dsync-proxy-server.c b/src/dsync/dsync-proxy-server.c index d51bd50a46..a1c8fcfce6 100644 --- a/src/dsync/dsync-proxy-server.c +++ b/src/dsync/dsync-proxy-server.c @@ -192,7 +192,8 @@ void dsync_proxy_server_deinit(struct dsync_proxy_server **_server) i_stream_unref(&server->get_input); pool_unref(&server->cmd_pool); timeout_remove(&server->to); - io_remove(&server->io); + if (server->io != NULL) + io_remove(&server->io); i_stream_destroy(&server->input); o_stream_destroy(&server->output); if (close(server->fd_in) < 0) diff --git a/src/dsync/dsync-worker-local.c b/src/dsync/dsync-worker-local.c index f43b8c45f1..d422222934 100644 --- a/src/dsync/dsync-worker-local.c +++ b/src/dsync/dsync-worker-local.c @@ -1706,6 +1706,7 @@ local_worker_msg_save(struct dsync_worker *_worker, i_error("Can't save message to mailbox %s: %s", mailbox_get_vname(dest_box), mail_storage_get_last_error(storage, NULL)); + mailbox_save_cancel(&save_ctx); dsync_worker_set_failure(_worker); callback(context); return;