dovecot-1.2: Auth workers: Use one full timeout per worker inste...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Oct 22 01:20:15 EEST 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/2e62e212f8a1
changeset: 8310:2e62e212f8a1
user: Timo Sirainen <tss at iki.fi>
date: Wed Oct 22 01:20:12 2008 +0300
description:
Auth workers: Use one full timeout per worker instead of a waking up every minute.
diffstat:
1 file changed, 41 insertions(+), 35 deletions(-)
src/auth/auth-worker-server.c | 76 ++++++++++++++++++++++-------------------
diffs (163 lines):
diff -r b8b75dcb3531 -r 2e62e212f8a1 src/auth/auth-worker-server.c
--- 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 auth_worker_connection {
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_req
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 @@ static struct auth_worker_connection *au
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 @@ static struct auth_worker_connection *au
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 @@ auth_worker_destroy(struct auth_worker_c
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 @@ static void auth_worker_handle_request(s
/* 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)
@@ -253,6 +274,13 @@ auth_worker_request_get(struct auth_work
request = auth_worker_request_lookup(conn, 0);
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,
@@ -313,33 +341,14 @@ void auth_worker_call(struct auth_reques
auth_worker_create();
}
- conn->last_used = ioloop_time;
+ 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--;
+ }
+ conn->request_count++;
conn->requests_left--;
- if (conn->request_count++ == 0)
- 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;
- }
- }
}
void auth_worker_server_init(void)
@@ -369,8 +378,6 @@ void auth_worker_server_init(void)
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 @@ void auth_worker_server_deinit(void)
}
array_free(&connections);
- timeout_remove(&to);
i_free(worker_socket_path);
}
More information about the dovecot-cvs
mailing list