# HG changeset patch # User Timo Sirainen # Date 1070412021 -7200 # Node ID 1e6ed8045f2bc391210dd5c944068fc23cea641d # Parent 0613ad9d503436d8e0f9008d5a8b3701f52858f7 Changed hash_foreach() to iterator. diff -r 0613ad9d5034 -r 1e6ed8045f2b src/auth/auth-client-connection.c --- a/src/auth/auth-client-connection.c Mon Dec 01 21:07:34 2003 +0200 +++ b/src/auth/auth-client-connection.c Wed Dec 03 02:40:21 2003 +0200 @@ -207,14 +207,6 @@ return conn; } -static void auth_request_hash_destroy(void *key __attr_unused__, void *value, - void *context __attr_unused__) -{ - struct auth_request *auth_request = value; - - auth_request->conn = NULL; -} - void auth_client_connection_destroy(struct auth_client_connection *conn) { struct auth_client_connection **pos; @@ -244,10 +236,19 @@ static void auth_client_connection_unref(struct auth_client_connection *conn) { + struct hash_iterate_context *iter; + void *key, *value; + if (--conn->refcount > 0) return; - hash_foreach(conn->auth_requests, auth_request_hash_destroy, NULL); + iter = hash_iterate_init(conn->auth_requests); + while (hash_iterate(iter, &key, &value)) { + struct auth_request *auth_request = value; + + auth_request->conn = NULL; + } + hash_iterate_deinit(iter); hash_destroy(conn->auth_requests); i_stream_unref(conn->input); @@ -256,20 +257,32 @@ pool_unref(conn->pool); } -static void auth_request_hash_timeout_check(void *key __attr_unused__, - void *value, void *context) +static void +auth_client_connection_check_timeouts(struct auth_client_connection *conn) { - struct auth_client_connection *conn = context; - struct auth_request *auth_request = value; + struct hash_iterate_context *iter; + void *key, *value; + unsigned int secs; + int destroy = FALSE; + + iter = hash_iterate_init(conn->auth_requests); + while (hash_iterate(iter, &key, &value)) { + struct auth_request *auth_request = value; - if (auth_request->created + AUTH_REQUEST_TIMEOUT < ioloop_time) { - i_warning("Login process has too old (%us) requests, " - "killing it.", - (unsigned int)(ioloop_time - auth_request->created)); + if (auth_request->created + AUTH_REQUEST_TIMEOUT < ioloop_time) { + secs = (unsigned int) (ioloop_time - + auth_request->created); + i_warning("Login process has too old (%us) requests, " + "killing it.", secs); + destroy = TRUE; + break; + } + } + hash_iterate_deinit(iter); + + if (destroy) auth_client_connection_destroy(conn); - hash_foreach_stop(); - } } static void request_timeout(void *context __attr_unused__) @@ -279,11 +292,7 @@ for (conn = master->clients; conn != NULL; conn = next) { next = conn->next; - - conn->refcount++; - hash_foreach(conn->auth_requests, - auth_request_hash_timeout_check, conn); - auth_client_connection_unref(conn); + auth_client_connection_check_timeouts(conn); } } diff -r 0613ad9d5034 -r 1e6ed8045f2b src/auth/db-ldap.c --- a/src/auth/db-ldap.c Mon Dec 01 21:07:34 2003 +0200 +++ b/src/auth/db-ldap.c Wed Dec 03 02:40:21 2003 +0200 @@ -226,19 +226,19 @@ return TRUE; } -static void hash_ldap_request_destroy(void *key __attr_unused__, - void *value, void *context) -{ - struct ldap_request *request = value; - struct ldap_connection *conn = context; - - request->callback(conn, request, NULL); - i_free(request); -} - static void ldap_conn_close(struct ldap_connection *conn) { - hash_foreach(conn->requests, hash_ldap_request_destroy, conn); + struct hash_iterate_context *iter; + void *key, *value; + + iter = hash_iterate_init(conn->requests); + while (hash_iterate(iter, &key, &value)) { + struct ldap_request *request = value; + + request->callback(conn, request, NULL); + i_free(request); + } + hash_iterate_deinit(iter); hash_clear(conn->requests, FALSE); conn->connected = FALSE; diff -r 0613ad9d5034 -r 1e6ed8045f2b src/imap-login/client.c --- a/src/imap-login/client.c Mon Dec 01 21:07:34 2003 +0200 +++ b/src/imap-login/client.c Wed Dec 03 02:40:21 2003 +0200 @@ -309,45 +309,40 @@ o_stream_flush(client->output); } -static void client_hash_destroy_oldest(void *key, void *value __attr_unused__, - void *context) +static void client_destroy_oldest(void) { - struct imap_client *client = key; - struct imap_client *const *destroy_clients; - buffer_t *destroy_buf = context; - size_t i, count; + struct hash_iterate_context *iter; + void *key, *value; + struct imap_client *destroy_buf[CLIENT_DESTROY_OLDEST_COUNT]; + int i; + + /* find the oldest clients and put them to destroy-buffer */ + memset(destroy_buf, 0, sizeof(destroy_buf)); - destroy_clients = buffer_get_data(destroy_buf, &count); - count /= sizeof(struct imap_client *); + iter = hash_iterate_init(clients); + while (hash_iterate(iter, &key, &value)) { + struct imap_client *client = key; - for (i = 0; i < count; i++) { - if (destroy_clients[i]->created > client->created) { - buffer_insert(destroy_buf, - i * sizeof(struct imap_client *), - &client, sizeof(struct imap_client *)); - break; + for (i = 0; i < CLIENT_DESTROY_OLDEST_COUNT; i++) { + if (destroy_buf[i] == NULL || + destroy_buf[i]->created > client->created) { + /* @UNSAFE */ + memmove(destroy_buf+i+1, destroy_buf+i, + sizeof(destroy_buf) - + (i+1) * sizeof(struct imap_client *)); + destroy_buf[i] = client; + break; + } } } -} - -static void client_destroy_oldest(void) -{ - struct imap_client *const *destroy_clients; - buffer_t *destroy_buf; - size_t i, count; - - /* find the oldest clients and put them to destroy-buffer */ - destroy_buf = buffer_create_static_hard(pool_datastack_create(), - sizeof(struct imap_client *) * - CLIENT_DESTROY_OLDEST_COUNT); - hash_foreach(clients, client_hash_destroy_oldest, destroy_buf); + hash_iterate_deinit(iter); /* then kill them */ - destroy_clients = buffer_get_data(destroy_buf, &count); - count /= sizeof(struct imap_client *); + for (i = 0; i < CLIENT_DESTROY_OLDEST_COUNT; i++) { + if (destroy_buf[i] == NULL) + break; - for (i = 0; i < count; i++) { - client_destroy(destroy_clients[i], + client_destroy(destroy_buf[i], "Disconnected: Connection queue full"); } } @@ -474,11 +469,8 @@ i_info("%s [%s]", text, addr); } -static void client_hash_check_idle(void *key, void *value __attr_unused__, - void *context __attr_unused__) +static void client_check_idle(struct imap_client *client) { - struct imap_client *client = key; - if (ioloop_time - client->last_input >= CLIENT_LOGIN_IDLE_TIMEOUT) { client_send_line(client, "* BYE Disconnected for inactivity."); client_destroy(client, "Disconnected: Inactivity"); @@ -487,7 +479,16 @@ static void idle_timeout(void *context __attr_unused__) { - hash_foreach(clients, client_hash_check_idle, NULL); + struct hash_iterate_context *iter; + void *key, *value; + + iter = hash_iterate_init(clients); + while (hash_iterate(iter, &key, &value)) { + struct imap_client *client = key; + + client_check_idle(client); + } + hash_iterate_deinit(iter); } unsigned int clients_get_count(void) @@ -495,31 +496,35 @@ return hash_size(clients); } -static void client_hash_check_io(void *key, void *value __attr_unused__, - void *context __attr_unused__) -{ - struct imap_client *client = key; - - if (client->input_blocked) { - client->input_blocked = FALSE; - client_input(client); - } -} - void clients_notify_auth_connected(void) { - hash_foreach(clients, client_hash_check_io, NULL); -} + struct hash_iterate_context *iter; + void *key, *value; + + iter = hash_iterate_init(clients); + while (hash_iterate(iter, &key, &value)) { + struct imap_client *client = key; -static void client_hash_destroy(void *key, void *value __attr_unused__, - void *context __attr_unused__) -{ - client_destroy(key, NULL); + if (client->input_blocked) { + client->input_blocked = FALSE; + client_input(client); + } + } + hash_iterate_deinit(iter); } void clients_destroy_all(void) { - hash_foreach(clients, client_hash_destroy, NULL); + struct hash_iterate_context *iter; + void *key, *value; + + iter = hash_iterate_init(clients); + while (hash_iterate(iter, &key, &value)) { + struct imap_client *client = key; + + client_destroy(client, NULL); + } + hash_iterate_deinit(iter); } void clients_init(void) diff -r 0613ad9d5034 -r 1e6ed8045f2b src/imap/imap-thread.c --- a/src/imap/imap-thread.c Mon Dec 01 21:07:34 2003 +0200 +++ b/src/imap/imap-thread.c Wed Dec 03 02:40:21 2003 +0200 @@ -898,21 +898,21 @@ (void)o_stream_send(ctx->output, str_data(str), str_len(str)); } -static void save_root_cb(void *key __attr_unused__, void *value, void *context) -{ - struct thread_context *ctx = context; - struct node *node = value; - - if (node->parent == NULL) - add_root(ctx, node); -} - static void mail_thread_finish(struct thread_context *ctx) { + struct hash_iterate_context *iter; + void *key, *value; struct node *node; /* (2) save root nodes and drop the msgids */ - hash_foreach(ctx->msgid_hash, save_root_cb, ctx); + iter = hash_iterate_init(ctx->msgid_hash); + while (hash_iterate(iter, &key, &value)) { + struct node *node = value; + + if (node->parent == NULL) + add_root(ctx, node); + } + hash_iterate_deinit(iter); /* drop the memory allocated for message-IDs and msgid_hash, reuse their memory for base subjects */ diff -r 0613ad9d5034 -r 1e6ed8045f2b src/lib-index/maildir/maildir-sync.c --- a/src/lib-index/maildir/maildir-sync.c Mon Dec 01 21:07:34 2003 +0200 +++ b/src/lib-index/maildir/maildir-sync.c Wed Dec 03 02:40:21 2003 +0200 @@ -361,15 +361,6 @@ return TRUE; } -static void uidlist_hash_get_filenames(void *key, void *value, void *context) -{ - buffer_t *buf = context; - struct maildir_hash_rec *hash_rec = value; - - if (ACTION(hash_rec) == MAILDIR_FILE_ACTION_NEW) - buffer_append(buf, (const void *) &key, sizeof(const char *)); -} - static int maildir_time_cmp(const void *p1, const void *p2) { const char *s1 = *((const char **) p1); @@ -393,6 +384,8 @@ static int maildir_full_sync_finish_new_mails(struct maildir_sync_context *ctx) { + struct hash_iterate_context *iter; + void *key, *value; const char *dir, **new_files; buffer_t *buf; unsigned int i; @@ -404,7 +397,16 @@ so we should get them to same order as they were created. */ buf = buffer_create_static_hard(ctx->pool, ctx->new_count * sizeof(const char *)); - hash_foreach(ctx->files, uidlist_hash_get_filenames, buf); + iter = hash_iterate_init(ctx->files); + while (hash_iterate(iter, &key, &value)) { + struct maildir_hash_rec *hash_rec = value; + + if (ACTION(hash_rec) == MAILDIR_FILE_ACTION_NEW) { + buffer_append(buf, (const void *) &key, + sizeof(const char *)); + } + } + hash_iterate_deinit(iter); i_assert(buffer_get_used_size(buf) == ctx->new_count * sizeof(const char *)); @@ -781,33 +783,11 @@ return ret; } -static void maildir_sync_hash_fix_allocs(void *key, void *value, void *context) -{ - struct maildir_sync_context *ctx = context; - struct maildir_hash_rec *hash_rec = value; - - switch (ACTION(hash_rec)) { - case MAILDIR_FILE_ACTION_NONE: - hash_remove(ctx->files, key); - break; - case MAILDIR_FILE_ACTION_EXPUNGE: - if (hash_rec->action & MAILDIR_FILE_FLAG_ALLOCED) { - /* we're getting here because our recently - inserted node is traversed as well */ - break; - } - - hash_rec->action |= MAILDIR_FILE_FLAG_ALLOCED; - hash_insert(ctx->files, p_strdup(ctx->pool, key), value); - break; - default: - break; - } -} - static int maildir_full_sync_dir(struct maildir_sync_context *ctx, int new_dir, DIR *dirp, struct dirent *d) { + struct hash_iterate_context *iter; + void *key, *value; struct maildir_hash_rec *hash_rec; void *orig_key, *orig_value; int newflag; @@ -864,7 +844,30 @@ /* records that are left to hash must not have any (filename) pointers to cache file. So remove none actions, and p_strdup() expunge actions. */ - hash_foreach(ctx->files, maildir_sync_hash_fix_allocs, ctx); + iter = hash_iterate_init(ctx->files); + while (hash_iterate(iter, &key, &value)) { + struct maildir_hash_rec *hash_rec = value; + + switch (ACTION(hash_rec)) { + case MAILDIR_FILE_ACTION_NONE: + hash_remove(ctx->files, key); + break; + case MAILDIR_FILE_ACTION_EXPUNGE: + if (hash_rec->action & MAILDIR_FILE_FLAG_ALLOCED) { + /* we're getting here because our recently + inserted node is traversed as well */ + break; + } + + hash_rec->action |= MAILDIR_FILE_FLAG_ALLOCED; + hash_insert(ctx->files, + p_strdup(ctx->pool, key), value); + break; + default: + break; + } + } + hash_iterate_deinit(iter); return TRUE; } diff -r 0613ad9d5034 -r 1e6ed8045f2b src/lib/hash.c --- a/src/lib/hash.c Mon Dec 01 21:07:34 2003 +0200 +++ b/src/lib/hash.c Wed Dec 03 02:40:21 2003 +0200 @@ -32,8 +32,6 @@ static int hash_resize(struct hash_table *table, int grow); -static int foreach_stop; - static int direct_cmp(const void *p1, const void *p2) { return p1 == p2 ? 0 : 1; @@ -321,37 +319,65 @@ return table->nodes_count; } -void hash_foreach(struct hash_table *table, hash_foreach_callback_t *callback, - void *context) +struct hash_iterate_context { + struct hash_table *table; + struct hash_node *next; + size_t pos; +}; + +struct hash_iterate_context *hash_iterate_init(struct hash_table *table) { - struct hash_node *node; - size_t i; + struct hash_iterate_context *ctx; hash_freeze(table); - foreach_stop = FALSE; - - for (i = 0; i < table->size; i++) { - node = &table->nodes[i]; + ctx = i_new(struct hash_iterate_context, 1); + ctx->table = table; + ctx->next = &table->nodes[0]; + return ctx; +} - do { - if (node->key != NULL) { - callback(node->key, node->value, context); - if (foreach_stop) { - table->frozen--; - return; - } +static struct hash_node *hash_iterate_next(struct hash_iterate_context *ctx, + struct hash_node *node) +{ + do { + if (node == NULL) { + if (++ctx->pos == ctx->table->size) { + ctx->pos--; + return NULL; } + node = &ctx->table->nodes[ctx->pos]; + } else { node = node->next; - } while (node != NULL); - } + } + } while (node->key == NULL); - hash_thaw(table); + return node; } -void hash_foreach_stop(void) +int hash_iterate(struct hash_iterate_context *ctx, + void **key_r, void **value_r) { - foreach_stop = TRUE; + struct hash_node *node; + + node = ctx->next; + if (node != NULL && node->key == NULL) + node = hash_iterate_next(ctx, node); + if (node == NULL) { + *key_r = *value_r = NULL; + return FALSE; + } + *key_r = node->key; + *value_r = node->value; + + ctx->next = hash_iterate_next(ctx, node); + return TRUE; +} + +void hash_iterate_deinit(struct hash_iterate_context *ctx) +{ + hash_thaw(ctx->table); + i_free(ctx); } void hash_freeze(struct hash_table *table) diff -r 0613ad9d5034 -r 1e6ed8045f2b src/lib/hash.h --- a/src/lib/hash.h Mon Dec 01 21:07:34 2003 +0200 +++ b/src/lib/hash.h Wed Dec 03 02:40:21 2003 +0200 @@ -5,7 +5,6 @@ typedef unsigned int hash_callback_t(const void *p); /* Returns 0 if the pointers are equal. */ typedef int hash_cmp_callback_t(const void *p1, const void *p2); -typedef void hash_foreach_callback_t(void *key, void *value, void *context); /* Create a new hash table. If initial_size is 0, the default value is used. If hash_cb or key_compare_cb is NULL, direct hashing/comparing is used. @@ -35,13 +34,13 @@ void hash_remove(struct hash_table *table, const void *key); size_t hash_size(struct hash_table *table); -/* Calls the given function for each node in hash table. You may safely - call hash_*() functions inside your function, but if you add any - new nodes, they may or may not be called for in this foreach loop. */ -void hash_foreach(struct hash_table *table, - hash_foreach_callback_t *callback, void *context); -/* Stop the active hash_foreach() loop */ -void hash_foreach_stop(void); +/* Iterates through all nodes in hash table. You may safely call hash_*() + functions while iterating, but if you add any new nodes, they may or may + not be called for in this iteration. */ +struct hash_iterate_context *hash_iterate_init(struct hash_table *table); +int hash_iterate(struct hash_iterate_context *ctx, + void **key_r, void **value_r); +void hash_iterate_deinit(struct hash_iterate_context *ctx); /* Hash table isn't resized, and removed nodes aren't removed from the list while hash table is freezed. Supports nesting. */ diff -r 0613ad9d5034 -r 1e6ed8045f2b src/login-common/ssl-proxy-gnutls.c --- a/src/login-common/ssl-proxy-gnutls.c Mon Dec 01 21:07:34 2003 +0200 +++ b/src/login-common/ssl-proxy-gnutls.c Wed Dec 03 02:40:21 2003 +0200 @@ -527,18 +527,18 @@ ssl_initialized = TRUE; } -static void ssl_proxy_destroy_hash(void *key __attr_unused__, void *value, - void *context __attr_unused__) -{ - ssl_proxy_destroy(value); -} - void ssl_proxy_deinit(void) { + struct hash_iterate_context *iter; + void *key, *value; + if (!ssl_initialized) return; - hash_foreach(ssl_proxies, ssl_proxy_destroy_hash, NULL); + iter = hash_iterate_init(ssl_proxies); + while (hash_iterate(iter, &key, &value)) + ssl_proxy_destroy(value); + hash_iterate_deinit(iter); hash_destroy(ssl_proxies); gnutls_certificate_free_cred(x509_cred); diff -r 0613ad9d5034 -r 1e6ed8045f2b src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Mon Dec 01 21:07:34 2003 +0200 +++ b/src/login-common/ssl-proxy-openssl.c Wed Dec 03 02:40:21 2003 +0200 @@ -451,18 +451,18 @@ ssl_initialized = TRUE; } -static void ssl_proxy_destroy_hash(void *key __attr_unused__, void *value, - void *context __attr_unused__) -{ - ssl_proxy_unref(value); -} - void ssl_proxy_deinit(void) { + struct hash_iterate_context *iter; + void *key, *value; + if (!ssl_initialized) return; - hash_foreach(ssl_proxies, ssl_proxy_destroy_hash, NULL); + iter = hash_iterate_init(ssl_proxies); + while (hash_iterate(iter, &key, &value)) + ssl_proxy_destroy(value); + hash_iterate_deinit(iter); hash_destroy(ssl_proxies); SSL_CTX_free(ssl_ctx); diff -r 0613ad9d5034 -r 1e6ed8045f2b src/master/auth-process.c --- a/src/master/auth-process.c Mon Dec 01 21:07:34 2003 +0200 +++ b/src/master/auth-process.c Wed Dec 03 02:40:21 2003 +0200 @@ -216,14 +216,10 @@ return p; } -static void request_hash_destroy(void *key __attr_unused__, - void *value, void *context __attr_unused__) -{ - auth_master_callback(NULL, NULL, value); -} - static void auth_process_destroy(struct auth_process *p) { + struct hash_iterate_context *iter; + void *key, *value; struct auth_process **pos; if (!p->initialized && io_loop_is_running(ioloop)) { @@ -239,7 +235,10 @@ } p->group->process_count--; - hash_foreach(p->requests, request_hash_destroy, NULL); + iter = hash_iterate_init(p->requests); + while (hash_iterate(iter, &key, &value)) + auth_master_callback(NULL, NULL, value); + hash_iterate_deinit(iter); hash_destroy(p->requests); i_stream_unref(p->input); diff -r 0613ad9d5034 -r 1e6ed8045f2b src/master/login-process.c --- a/src/master/login-process.c Mon Dec 01 21:07:34 2003 +0200 +++ b/src/master/login-process.c Wed Dec 03 02:40:21 2003 +0200 @@ -506,15 +506,15 @@ p->group->wanted_processes_count = 0; } -static void login_hash_destroy(void *key __attr_unused__, void *value, - void *context __attr_unused__) -{ - login_process_destroy(value); -} - void login_processes_destroy_all(void) { - hash_foreach(processes, login_hash_destroy, NULL); + struct hash_iterate_context *iter; + void *key, *value; + + iter = hash_iterate_init(processes); + while (hash_iterate(iter, &key, &value)) + login_process_destroy(value); + hash_iterate_deinit(iter); while (login_groups != NULL) { struct login_group *group = login_groups; diff -r 0613ad9d5034 -r 1e6ed8045f2b src/pop3-login/client.c --- a/src/pop3-login/client.c Mon Dec 01 21:07:34 2003 +0200 +++ b/src/pop3-login/client.c Wed Dec 03 02:40:21 2003 +0200 @@ -189,45 +189,40 @@ o_stream_flush(client->output); } -static void client_hash_destroy_oldest(void *key, void *value __attr_unused__, - void *context) +static void client_destroy_oldest(void) { - struct pop3_client *client = key; - struct pop3_client *const *destroy_clients; - buffer_t *destroy_buf = context; - size_t i, count; + struct hash_iterate_context *iter; + void *key, *value; + struct pop3_client *destroy_buf[CLIENT_DESTROY_OLDEST_COUNT]; + int i; + + /* find the oldest clients and put them to destroy-buffer */ + memset(destroy_buf, 0, sizeof(destroy_buf)); - destroy_clients = buffer_get_data(destroy_buf, &count); - count /= sizeof(struct pop3_client *); + iter = hash_iterate_init(clients); + while (hash_iterate(iter, &key, &value)) { + struct pop3_client *client = key; - for (i = 0; i < count; i++) { - if (destroy_clients[i]->created > client->created) { - buffer_insert(destroy_buf, - i * sizeof(struct pop3_client *), - &client, sizeof(struct pop3_client *)); - break; + for (i = 0; i < CLIENT_DESTROY_OLDEST_COUNT; i++) { + if (destroy_buf[i] == NULL || + destroy_buf[i]->created > client->created) { + /* @UNSAFE */ + memmove(destroy_buf+i+1, destroy_buf+i, + sizeof(destroy_buf) - + (i+1) * sizeof(struct pop3_client *)); + destroy_buf[i] = client; + break; + } } } -} - -static void client_destroy_oldest(void) -{ - struct pop3_client *const *destroy_clients; - buffer_t *destroy_buf; - size_t i, count; - - /* find the oldest clients and put them to destroy-buffer */ - destroy_buf = buffer_create_static_hard(pool_datastack_create(), - sizeof(struct pop3_client *) * - CLIENT_DESTROY_OLDEST_COUNT); - hash_foreach(clients, client_hash_destroy_oldest, destroy_buf); + hash_iterate_deinit(iter); /* then kill them */ - destroy_clients = buffer_get_data(destroy_buf, &count); - count /= sizeof(struct pop3_client *); + for (i = 0; i < CLIENT_DESTROY_OLDEST_COUNT; i++) { + if (destroy_buf[i] == NULL) + break; - for (i = 0; i < count; i++) { - client_destroy(destroy_clients[i], + client_destroy(destroy_buf[i], "Disconnected: Connection queue full"); } } @@ -344,18 +339,24 @@ i_info("%s [%s]", text, addr); } -static void client_hash_check_idle(void *key, void *value __attr_unused__, - void *context __attr_unused__) +static void client_check_idle(struct pop3_client *client) { - struct pop3_client *client = key; - if (ioloop_time - client->last_input >= CLIENT_LOGIN_IDLE_TIMEOUT) client_destroy(client, "Disconnected: Inactivity"); } static void idle_timeout(void *context __attr_unused__) { - hash_foreach(clients, client_hash_check_idle, NULL); + struct hash_iterate_context *iter; + void *key, *value; + + iter = hash_iterate_init(clients); + while (hash_iterate(iter, &key, &value)) { + struct pop3_client *client = key; + + client_check_idle(client); + } + hash_iterate_deinit(iter); } unsigned int clients_get_count(void) @@ -363,31 +364,35 @@ return hash_size(clients); } -static void client_hash_check_io(void *key, void *value __attr_unused__, - void *context __attr_unused__) -{ - struct pop3_client *client = key; - - if (client->input_blocked) { - client->input_blocked = FALSE; - client_input(client); - } -} - void clients_notify_auth_connected(void) { - hash_foreach(clients, client_hash_check_io, NULL); -} + struct hash_iterate_context *iter; + void *key, *value; + + iter = hash_iterate_init(clients); + while (hash_iterate(iter, &key, &value)) { + struct pop3_client *client = key; -static void client_hash_destroy(void *key, void *value __attr_unused__, - void *context __attr_unused__) -{ - client_destroy(key, NULL); + if (client->input_blocked) { + client->input_blocked = FALSE; + client_input(client); + } + } + hash_iterate_deinit(iter); } void clients_destroy_all(void) { - hash_foreach(clients, client_hash_destroy, NULL); + struct hash_iterate_context *iter; + void *key, *value; + + iter = hash_iterate_init(clients); + while (hash_iterate(iter, &key, &value)) { + struct pop3_client *client = key; + + client_destroy(client, NULL); + } + hash_iterate_deinit(iter); } void clients_init(void)