]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dsync: Error handling fixes.
authorTimo Sirainen <tss@iki.fi>
Mon, 25 Oct 2010 17:53:04 +0000 (18:53 +0100)
committerTimo Sirainen <tss@iki.fi>
Mon, 25 Oct 2010 17:53:04 +0000 (18:53 +0100)
src/dsync/dsync-proxy-client.c
src/dsync/dsync-proxy-server.c
src/dsync/dsync-worker-local.c

index 9da39e7ab4cc8036cf4933798ce1168a156dec10..f676bfd641d7274e087e2fe1d58eeff3f1c12fa1 100644 (file)
@@ -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
index d51bd50a46d7800017a3d1ab08a4b579afda6946..a1c8fcfce6e0bf66bba008cb59cbce2bf63f90cf 100644 (file)
@@ -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)
index f43b8c45f1ef62dff640460189bcecb24985fde7..d4222229343704b5c643d4a0628fd940c4e77861 100644 (file)
@@ -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;