Mercurial > dovecot > core-2.2
changeset 21498:e74e1269959f
indexer: Don't send more requests directly from worker status callback
This causes assert-crashes when workers disconnect while having multiple
requests:
indexer: Error: Indexer worker disconnected, discarding 2 requests for user@domain
indexer: Panic: file indexer.c: line 69 (queue_try_send_more): assertion failed: (worker_connection_is_connected(conn))
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Mon, 06 Feb 2017 14:05:47 +0200 |
parents | 1f04b10661cc |
children | b3aa71d6fd25 |
files | src/indexer/indexer.c |
diffstat | 1 files changed, 11 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/src/indexer/indexer.c Sun Feb 05 16:49:05 2017 +0200 +++ b/src/indexer/indexer.c Mon Feb 06 14:05:47 2017 +0200 @@ -1,6 +1,7 @@ /* Copyright (c) 2011-2017 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "ioloop.h" #include "restrict-access.h" #include "process-title.h" #include "master-service.h" @@ -18,6 +19,7 @@ static const struct master_service_settings *set; static struct indexer_queue *queue; static struct worker_pool *worker_pool; +static struct timeout *to_send_more; void indexer_refresh_proctitle(void) { @@ -59,6 +61,9 @@ struct worker_connection *conn; struct indexer_request *request; + if (to_send_more != NULL) + timeout_remove(&to_send_more); + while ((request = indexer_queue_request_peek(queue)) != NULL) { conn = worker_pool_find_username_connection(worker_pool, request->username); @@ -98,8 +103,10 @@ i_free(request); /* if this was the last request for the connection, we can send more - through it */ - queue_try_send_more(queue); + through it. delay it a bit, since we may be coming here from + worker_connection_disconnect() and we want to finish it up. */ + if (to_send_more == NULL) + to_send_more = timeout_add_short(0, queue_try_send_more, queue); } int main(int argc, char *argv[]) @@ -132,6 +139,8 @@ indexer_clients_destroy_all(); worker_pool_deinit(&worker_pool); indexer_queue_deinit(&queue); + if (to_send_more != NULL) + timeout_remove(&to_send_more); master_service_deinit(&master_service); return 0;