From: Timo Sirainen Date: Fri, 28 Oct 2022 14:57:03 +0000 (+0300) Subject: replicator: Add replicator_queue_count() and replicator_queue_peek() X-Git-Tag: 2.3.20~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=95ec1043e086624f4600222b278e9deafa731628;p=thirdparty%2Fdovecot%2Fcore.git replicator: Add replicator_queue_count() and replicator_queue_peek() These will be useful for the following unit test. --- diff --git a/src/replication/replicator/replicator-queue.c b/src/replication/replicator/replicator-queue.c index 69aef700bc..c5abbf6a85 100644 --- a/src/replication/replicator/replicator-queue.c +++ b/src/replication/replicator/replicator-queue.c @@ -257,19 +257,26 @@ void replicator_queue_remove(struct replicator_queue *queue, queue->change_callback(queue->change_context); } +unsigned int replicator_queue_count(struct replicator_queue *queue) +{ + return priorityq_count(queue->user_queue); +} + bool replicator_queue_want_sync_now(struct replicator_user *user, unsigned int *next_secs_r) { time_t next_sync = replicator_user_next_sync_time(user); - if (next_sync <= ioloop_time) + if (next_sync <= ioloop_time) { + *next_secs_r = 0; return TRUE; + } *next_secs_r = next_sync - ioloop_time; return FALSE; } struct replicator_user * -replicator_queue_pop(struct replicator_queue *queue, - unsigned int *next_secs_r) +replicator_queue_peek(struct replicator_queue *queue, + unsigned int *next_secs_r) { struct priorityq_item *item; struct replicator_user *user; @@ -281,12 +288,25 @@ replicator_queue_pop(struct replicator_queue *queue, return NULL; } user = (struct replicator_user *)item; - if (!replicator_queue_want_sync_now(user, next_secs_r)) { + (void)replicator_queue_want_sync_now(user, next_secs_r); + return user; +} + +struct replicator_user * +replicator_queue_pop(struct replicator_queue *queue, + unsigned int *next_secs_r) +{ + struct replicator_user *user; + + user = replicator_queue_peek(queue, next_secs_r); + if (*next_secs_r > 0) { /* we don't want to sync the user yet */ return NULL; } - priorityq_remove(queue->user_queue, &user->item); - user->popped = TRUE; + if (user != NULL) { + priorityq_remove(queue->user_queue, &user->item); + user->popped = TRUE; + } return user; } diff --git a/src/replication/replicator/replicator-queue.h b/src/replication/replicator/replicator-queue.h index 8a8a05ab76..4e021e20bd 100644 --- a/src/replication/replicator/replicator-queue.h +++ b/src/replication/replicator/replicator-queue.h @@ -64,7 +64,15 @@ void replicator_queue_add_sync_callback(struct replicator_queue *queue, /* Remove user from replication queue and free it. */ void replicator_queue_remove(struct replicator_queue *queue, struct replicator_user **user); +/* Return the number of users in the queue. */ +unsigned int replicator_queue_count(struct replicator_queue *queue); +/* Return the next user from replication queue and how many seconds from now + the returned user should be synced (0 = immediately). Returns NULL only if + there are no users in the queue. */ +struct replicator_user * +replicator_queue_peek(struct replicator_queue *queue, + unsigned int *next_secs_r); /* Return the next user from replication queue, and remove it from the queue. If there's nothing to be replicated currently, returns NULL and sets next_secs_r to when there should be more work to do. */