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);
}