From: Timo Sirainen Date: Sat, 25 Nov 2017 08:05:27 +0000 (+0200) Subject: director: Delay sorting users until there are no more user iterators X-Git-Tag: 2.2.34~214 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4207e64a04998380c88f94b159ffaf1cddfeec5d;p=thirdparty%2Fdovecot%2Fcore.git director: Delay sorting users until there are no more user iterators This shouldn't have normally happened. Only when an outgoing handshake was going on at the same time as a) another outgoing handshake was going on, or b) doveadm was doing HOST-RESET-USERS --- diff --git a/src/director/user-directory.c b/src/director/user-directory.c index 2d892a4094..05b05bb27f 100644 --- a/src/director/user-directory.c +++ b/src/director/user-directory.c @@ -35,6 +35,8 @@ struct user_directory { unsigned int user_near_expiring_secs; struct timeout *to_expire; time_t to_expire_timestamp; + + bool sort_pending; }; static void user_move_iters(struct user_directory *dir, struct user *user) @@ -199,11 +201,21 @@ void user_directory_sort(struct user_directory *dir) struct user *user, *const *userp; unsigned int i, users_count = hash_table_count(dir->hash); + dir->sort_pending = FALSE; + if (users_count == 0) { i_assert(dir->head == NULL); return; } + if (array_count(&dir->iters) > 0) { + /* We can't sort the directory while there are iterators + or they'll skip users. Do the sort after there are no more + iterators. */ + dir->sort_pending = TRUE; + return; + } + /* place all users into array and sort it */ i_array_init(&users, users_count); user = dir->head; @@ -318,5 +330,7 @@ void user_directory_iter_deinit(struct user_directory_iter **_iter) break; } } + if (array_count(&iter->dir->iters) == 0 && iter->dir->sort_pending) + user_directory_sort(iter->dir); i_free(iter); }