Hello. I am on an irrational crusade against unneeded timers (it started as a well-meaining power saving exercise), and I have now started removing polling in Dovecot.
Attached is a patch with the work I did on this the other night. Would something like that be acceptable, or should I make it in a different way? There seems to be no one-shot timer support, right? Is there a Dovecot coding style document? (I did notice that there appears to be an 80 char width that I exceeded) Cheers, Anders
diff -ur dovecot-1.0.9-orig/src/auth/auth-request-handler.c dovecot-1.0.9/src/auth/auth-request-handler.c --- dovecot-1.0.9-orig/src/auth/auth-request-handler.c 2007-12-11 19:52:08.000000000 +0100 +++ dovecot-1.0.9/src/auth/auth-request-handler.c 2007-12-31 01:16:57.000000000 +0100 @@ -30,6 +30,8 @@ static buffer_t *auth_failures_buf; static struct timeout *to_auth_failures; +static void auth_failure_timeout(void *context __attr_unused__); + struct auth_request_handler * auth_request_handler_create(struct auth *auth, auth_request_callback_t *callback, void *context, @@ -217,6 +219,8 @@ handler->refcount++; buffer_append(auth_failures_buf, &request, sizeof(request)); + if (!to_auth_failures) + to_auth_failures = timeout_add(1000, auth_failure_timeout, NULL); } break; } @@ -493,6 +497,7 @@ auth_request_unref(&auth_request[i]); } buffer_set_used_size(auth_failures_buf, 0); + timeout_remove(&to_auth_failures); } static void auth_failure_timeout(void *context __attr_unused__) @@ -503,12 +508,12 @@ void auth_request_handler_init(void) { auth_failures_buf = buffer_create_dynamic(default_pool, 1024); - to_auth_failures = timeout_add(2000, auth_failure_timeout, NULL); } void auth_request_handler_deinit(void) { auth_request_handler_flush_failures(); buffer_free(auth_failures_buf); - timeout_remove(&to_auth_failures); + if (to_auth_failures) + timeout_remove(&to_auth_failures); } diff -ur dovecot-1.0.9-orig/src/imap-login/client.c dovecot-1.0.9/src/imap-login/client.c --- dovecot-1.0.9-orig/src/imap-login/client.c 2007-12-11 19:52:08.000000000 +0100 +++ dovecot-1.0.9/src/imap-login/client.c 2007-12-31 01:03:17.000000000 +0100 @@ -53,6 +53,37 @@ static struct hash_table *clients; static struct timeout *to_idle; +static void idle_timeout(void *context __attr_unused__); + +static void setup_timeout(void) +{ + struct hash_iterate_context *iter; + void *key, *value; + int timeout = INT_MAX; + + iter = hash_iterate_init(clients); + while (hash_iterate(iter, &key, &value)) { + struct imap_client *client = key; + int timeout_proposal; + + if (!client->waiting_sent && + (client->common.authenticating || !client->greeting_sent)) { + timeout_proposal = (client->last_input + AUTH_WAITING_TIMEOUT) - ioloop_time; + } else { + timeout_proposal = (client->last_input + CLIENT_LOGIN_IDLE_TIMEOUT) - ioloop_time; + } + + if (timeout_proposal < timeout) + timeout = timeout_proposal; + } + hash_iterate_deinit(iter); + + if (to_idle) + timeout_remove(&to_idle); + to_idle = timeout_add(1000*timeout, idle_timeout, NULL); +} + + static void client_set_title(struct imap_client *client) { const char *addr; @@ -349,6 +380,7 @@ struct imap_client *client = context; client->last_input = ioloop_time; + setup_timeout(); if (!client_read(client)) return; @@ -455,6 +487,7 @@ client->last_input = ioloop_time; hash_insert(clients, client, client); + setup_timeout(); main_ref(); @@ -652,7 +685,6 @@ void clients_init(void) { clients = hash_create(default_pool, default_pool, 128, NULL, NULL); - to_idle = timeout_add(1000, idle_timeout, NULL); } void clients_deinit(void) @@ -660,5 +692,6 @@ clients_destroy_all(); hash_destroy(clients); - timeout_remove(&to_idle); + if (to_idle) + timeout_remove(&to_idle); } diff -ur dovecot-1.0.9-orig/src/pop3-login/client.c dovecot-1.0.9/src/pop3-login/client.c --- dovecot-1.0.9-orig/src/pop3-login/client.c 2007-12-11 19:52:09.000000000 +0100 +++ dovecot-1.0.9/src/pop3-login/client.c 2007-12-30 23:43:19.000000000 +0100 @@ -46,6 +46,31 @@ static struct hash_table *clients; static struct timeout *to_idle; +static void idle_timeout(void *context __attr_unused__); + +static void setup_timeout(void) +{ + struct hash_iterate_context *iter; + void *key, *value; + int timeout = INT_MAX; + + iter = hash_iterate_init(clients); + while (hash_iterate(iter, &key, &value)) { + struct pop3_client *client = key; + int timeout_proposal; + + timeout_proposal = (client->last_input + CLIENT_LOGIN_IDLE_TIMEOUT) - ioloop_time; + if (timeout_proposal < timeout) { + timeout = timeout_proposal; + } + } + hash_iterate_deinit(iter); + + if (to_idle) + timeout_remove(&to_idle); + to_idle = timeout_add(1000*timeout, idle_timeout, NULL); +} + static void client_set_title(struct pop3_client *client) { const char *addr; @@ -211,6 +236,7 @@ char *line, *args; client->last_input = ioloop_time; + setup_timeout(); if (!client_read(client)) return; @@ -341,6 +367,8 @@ client->last_input = ioloop_time; hash_insert(clients, client, client); + setup_timeout(); + main_ref(); client->auth_connected = auth_client_is_connected(auth_client); @@ -481,6 +509,8 @@ client_check_idle(client); } hash_iterate_deinit(iter); + + setup_timeout(); } unsigned int clients_get_count(void) @@ -522,7 +552,6 @@ void clients_init(void) { clients = hash_create(default_pool, default_pool, 128, NULL, NULL); - to_idle = timeout_add(1000, idle_timeout, NULL); } void clients_deinit(void) @@ -530,5 +559,6 @@ clients_destroy_all(); hash_destroy(clients); - timeout_remove(&to_idle); + if (to_idle) + timeout_remove(&to_idle); }