Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8310:2e62e212f8a1 HEAD
Auth workers: Use one full timeout per worker instead of a waking up every minute.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 22 Oct 2008 01:20:12 +0300 |
parents | b8b75dcb3531 |
children | 2792b3a9b67a |
files | src/auth/auth-worker-server.c |
diffstat | 1 files changed, 40 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/auth-worker-server.c Wed Oct 22 01:07:48 2008 +0300 +++ b/src/auth/auth-worker-server.c Wed Oct 22 01:20:12 2008 +0300 @@ -14,7 +14,8 @@ #include <unistd.h> #define AUTH_WORKER_MAX_OUTBUF_SIZE 10240 -#define AUTH_WORKER_MAX_IDLE_TIME (60*30) +#define AUTH_WORKER_LOOKUP_TIMEOUT_SECS 60 +#define AUTH_WORKER_MAX_IDLE_SECS (60*30) struct auth_worker_request { unsigned int id; @@ -28,11 +29,11 @@ struct io *io; struct istream *input; struct ostream *output; + struct timeout *to; unsigned int id_counter; ARRAY_DEFINE(requests, struct auth_worker_request); - time_t last_used; unsigned int request_count; unsigned int requests_left; }; @@ -43,9 +44,20 @@ static unsigned int auth_workers_max_request_count; static char *worker_socket_path; -static struct timeout *to; static void worker_input(struct auth_worker_connection *conn); +static void auth_worker_destroy(struct auth_worker_connection *conn, + const char *reason); + +static void auth_worker_idle_timeout(struct auth_worker_connection *conn) +{ + i_assert(array_count(&conn->requests) == 0); + + if (idle_count > 1) + auth_worker_destroy(conn, NULL); + else + timeout_reset(conn->to); +} static struct auth_worker_connection *auth_worker_create(void) { @@ -87,6 +99,8 @@ conn->io = io_add(fd, IO_READ, worker_input, conn); i_array_init(&conn->requests, 16); conn->requests_left = auth_workers_max_request_count; + conn->to = timeout_add(AUTH_WORKER_MAX_IDLE_SECS * 1000, + auth_worker_idle_timeout, conn); idle_count++; @@ -94,8 +108,8 @@ return conn; } -static void -auth_worker_destroy(struct auth_worker_connection *conn, const char *reason) +static void auth_worker_destroy(struct auth_worker_connection *conn, + const char *reason) { struct auth_worker_connection **connp; struct auth_worker_request *requests; @@ -135,6 +149,7 @@ io_remove(&conn->io); i_stream_destroy(&conn->input); o_stream_destroy(&conn->output); + timeout_remove(&conn->to); if (close(conn->fd) < 0) i_error("close(auth worker) failed: %m"); @@ -198,8 +213,14 @@ /* update counters */ conn->request_count--; - if (conn->request_count == 0) + if (conn->request_count > 0) + timeout_reset(conn->to); + else { + timeout_remove(&conn->to); + conn->to = timeout_add(AUTH_WORKER_MAX_IDLE_SECS * 1000, + auth_worker_idle_timeout, conn); idle_count++; + } } static void worker_input(struct auth_worker_connection *conn) @@ -255,6 +276,13 @@ return request != NULL ? request : array_append_space(&conn->requests); } +static void auth_worker_call_timeout(struct auth_worker_connection *conn) +{ + i_assert(array_count(&conn->requests) > 0); + + auth_worker_destroy(conn, "Lookup timed out"); +} + void auth_worker_call(struct auth_request *auth_request, struct auth_stream_reply *data, auth_worker_callback_t *callback) @@ -313,33 +341,14 @@ auth_worker_create(); } - conn->last_used = ioloop_time; - conn->requests_left--; - if (conn->request_count++ == 0) + if (conn->request_count == 0) { + timeout_remove(&conn->to); + conn->to = timeout_add(AUTH_WORKER_MAX_IDLE_SECS * 1000, + auth_worker_call_timeout, conn); idle_count--; -} - -static void auth_worker_timeout(void *context ATTR_UNUSED) -{ - struct auth_worker_connection **conn; - unsigned int i, count; - - if (idle_count <= 1) - return; - - /* remove connections which we haven't used for a long time. - this works because auth_worker_find_free() always returns the - first free connection. */ - conn = array_get_modifiable(&connections, &count); - for (i = 0; i < count; i++) { - if (conn[i]->last_used + - AUTH_WORKER_MAX_IDLE_TIME < ioloop_time) { - /* remove just one. easier.. Also in case of buggy, - this */ - auth_worker_destroy(conn[i], "Timed out"); - break; - } } + conn->request_count++; + conn->requests_left--; } void auth_worker_server_init(void) @@ -369,8 +378,6 @@ auth_workers_max_request_count = (unsigned int)-1; i_array_init(&connections, 16); - to = timeout_add(1000 * 60, auth_worker_timeout, NULL); - auth_worker_create(); } @@ -387,6 +394,5 @@ } array_free(&connections); - timeout_remove(&to); i_free(worker_socket_path); }