Mercurial > dovecot > original-hg > dovecot-2.2
changeset 16797:8b3634d4c362
auth: Fixed user iteration hang due to earlier stream corking changes.
Also fixed process title updating for auth-worker process during LIST.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 21 Sep 2013 05:03:03 +0300 |
parents | 09f5e8d6b8d4 |
children | 2323c451150f |
files | src/auth/auth-master-connection.c src/auth/auth-worker-client.c |
diffstat | 2 files changed, 44 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/auth-master-connection.c Sat Sep 21 04:48:52 2013 +0300 +++ b/src/auth/auth-master-connection.c Sat Sep 21 05:03:03 2013 +0300 @@ -447,8 +447,10 @@ master_input_list_finish(ctx); return 1; } - if (ret > 0) + if (ret > 0) { + o_stream_cork(ctx->conn->output); userdb_blocking_iter_next(ctx->iter); + } return 1; } @@ -502,6 +504,8 @@ } if (o_stream_get_buffer_used_size(ctx->conn->output) < MAX_OUTBUF_SIZE) userdb_blocking_iter_next(ctx->iter); + else + o_stream_uncork(ctx->conn->output); } static bool
--- a/src/auth/auth-worker-client.c Sat Sep 21 04:48:52 2013 +0300 +++ b/src/auth/auth-worker-client.c Sat Sep 21 05:03:03 2013 +0300 @@ -19,6 +19,7 @@ #define OUTBUF_THROTTLE_SIZE (1024*10) #define CLIENT_STATE_HANDSHAKE "handshaking" +#define CLIENT_STATE_ITER "iterating users" #define CLIENT_STATE_IDLE "idling" #define CLIENT_STATE_STOP "waiting for shutdown" @@ -413,6 +414,27 @@ return TRUE; } +static void +auth_worker_client_idle_kill(struct auth_worker_client *client ATTR_UNUSED) +{ + auth_worker_client_send_shutdown(); +} + +static void +auth_worker_client_set_idle_timeout(struct auth_worker_client *client) +{ + unsigned int idle_kill_secs; + + i_assert(client->to_idle == NULL); + + idle_kill_secs = master_service_get_idle_kill_secs(master_service); + if (idle_kill_secs > 0) { + client->to_idle = timeout_add(idle_kill_secs * 1000, + auth_worker_client_idle_kill, + client); + } +} + static void list_iter_deinit(struct auth_worker_list_context *ctx) { struct auth_worker_client *client = ctx->client; @@ -429,11 +451,14 @@ auth_worker_send_reply(client, str); client->io = io_add(client->fd, IO_READ, auth_worker_input, client); - o_stream_uncork(ctx->client->output); + auth_worker_client_set_idle_timeout(client); + o_stream_set_flush_callback(client->output, auth_worker_output, client); auth_request_unref(&ctx->auth_request); auth_worker_client_unref(&client); i_free(ctx); + + auth_worker_refresh_proctitle(CLIENT_STATE_IDLE); } static void list_iter_callback(const char *user, void *context) @@ -449,6 +474,8 @@ return; } + if (!ctx->sending) + o_stream_cork(ctx->client->output); T_BEGIN { str = t_str_new(128); str_printfa(str, "%u\t*\t%s\n", ctx->auth_request->id, user); @@ -476,9 +503,12 @@ } } while (ctx->sent && o_stream_get_buffer_used_size(ctx->client->output) <= OUTBUF_THROTTLE_SIZE); + o_stream_uncork(ctx->client->output); ctx->sending = FALSE; if (ctx->done) list_iter_deinit(ctx); + else + o_stream_set_flush_pending(ctx->client->output, TRUE); } static int auth_worker_list_output(struct auth_worker_list_context *ctx) @@ -528,7 +558,9 @@ } io_remove(&ctx->client->io); - o_stream_cork(ctx->client->output); + if (ctx->client->to_idle != NULL) + timeout_remove(&ctx->client->to_idle); + o_stream_set_flush_callback(ctx->client->output, auth_worker_list_output, ctx); ctx->iter = ctx->auth_request->userdb->userdb->iface-> @@ -566,7 +598,8 @@ i_error("BUG: Auth-worker received unknown command: %s", args[1]); } - auth_worker_refresh_proctitle(CLIENT_STATE_IDLE); + if (client->io != NULL) + auth_worker_refresh_proctitle(CLIENT_STATE_IDLE); return ret; } @@ -671,17 +704,10 @@ return 1; } -static void -auth_worker_client_idle_kill(struct auth_worker_client *client ATTR_UNUSED) -{ - auth_worker_client_send_shutdown(); -} - struct auth_worker_client * auth_worker_client_create(struct auth *auth, int fd) { struct auth_worker_client *client; - unsigned int idle_kill_secs; client = i_new(struct auth_worker_client, 1); client->refcount = 1; @@ -694,15 +720,9 @@ o_stream_set_no_error_handling(client->output, TRUE); o_stream_set_flush_callback(client->output, auth_worker_output, client); client->io = io_add(fd, IO_READ, auth_worker_input, client); + auth_worker_client_set_idle_timeout(client); auth_worker_refresh_proctitle(CLIENT_STATE_HANDSHAKE); - idle_kill_secs = master_service_get_idle_kill_secs(master_service); - if (idle_kill_secs > 0) { - client->to_idle = timeout_add(idle_kill_secs * 1000, - auth_worker_client_idle_kill, - client); - } - auth_worker_client = client; if (auth_worker_client_error) auth_worker_client_send_error(); @@ -767,7 +787,8 @@ o_stream_nsend_str(auth_worker_client->output, "SUCCESS\n"); auth_worker_client->error_sent = FALSE; } - auth_worker_refresh_proctitle(CLIENT_STATE_IDLE); + if (auth_worker_client->io != NULL) + auth_worker_refresh_proctitle(CLIENT_STATE_IDLE); } void auth_worker_client_send_shutdown(void)