queue: add requeue, fix unqueue_matching

Synchronized with emane.git's implementation of this code which
includes a unit test.

This commit also fixes two bugs in unqueue_matching and one inb
unqueue:

- unqueue_matching was returning the wrong pointer when
  there was no match

- both unqueue_matching and unqueue were not clearing the vacated
  queue entry after removing the item
This commit is contained in:
Michael Cook
2020-10-20 09:04:23 -04:00
parent d449a4de8a
commit 6dd80ffd2f
5 changed files with 375 additions and 53 deletions
+21 -6
View File
@@ -32,15 +32,30 @@
#define MAX_QUEUE_SIZE 512
typedef struct queue_t {
void *items[MAX_QUEUE_SIZE];
size_t read_index, write_index;
size_t num_items;
pthread_mutex_t mutex;
typedef struct queue_t
{
void *items[MAX_QUEUE_SIZE];
size_t read_index, write_index;
size_t num_items;
pthread_mutex_t mutex;
} queue_t;
void init_queue(queue_t *q);
bool put_queue(queue_t *q, void *item);
void *get_queue(queue_t *q);
/* Put the given item back onto this queue at the head.
(The next call to put_queue would return this item.)
Return true if successful, false if the queue was full */
bool requeue(queue_t *q, void *item);
/* Remove the last item queued.
Return the item or NULL if the queue was empty */
void *unqueue(queue_t *q);
typedef bool queue_matcher_t(void *wanted, void *candidate);
/* Unqueue the most recently queued item for watch `matcher(wanted, candidate)`
returns true where `candidate` is an item currently on the queue.
Returns the candidate item, or NULL if none matches */
void *unqueue_matching(queue_t *q, queue_matcher_t *matcher, void *wanted);