Make the thread queue walk function take a cookie to the callback

and implement a _clear() function to clear out the queue
This commit is contained in:
Nils O. Selåsdal
2013-10-03 22:04:33 +02:00
parent 4310414b49
commit d9517ad868
3 changed files with 77 additions and 19 deletions
+46 -6
View File
@@ -199,19 +199,21 @@ int uc_thread_queue_tryget(struct uc_threadqueue *queue,
}
static void uc_thread_queue_walk_unlocked(struct uc_threadqueue *queue,
uc_thread_queue_walk_func walk_func)
uc_thread_queue_walk_func walk_func,
void *cookie)
{
struct uc_threadmsg *p;
struct uc_threadmsg *next;
for(p = queue->first; p; p = next) {
next = p->next;
walk_func(p);
walk_func(p, cookie);
}
}
int uc_thread_queue_walk(struct uc_threadqueue *queue,
uc_thread_queue_walk_func walk_func)
uc_thread_queue_walk_func walk_func,
void *cookie)
{
if (queue == NULL || !walk_func) {
return EINVAL;
@@ -219,7 +221,7 @@ int uc_thread_queue_walk(struct uc_threadqueue *queue,
pthread_mutex_lock(&queue->mutex);
uc_thread_queue_walk_unlocked(queue, walk_func);
uc_thread_queue_walk_unlocked(queue, walk_func, cookie);
pthread_mutex_unlock(&queue->mutex);
@@ -227,7 +229,8 @@ int uc_thread_queue_walk(struct uc_threadqueue *queue,
}
int uc_thread_queue_destroy(struct uc_threadqueue *queue,
uc_thread_queue_walk_func free_func)
uc_thread_queue_walk_func free_func,
void *cookie)
{
int rc;
@@ -250,7 +253,7 @@ int uc_thread_queue_destroy(struct uc_threadqueue *queue,
}
if (free_func) {
uc_thread_queue_walk_unlocked(queue, free_func);
uc_thread_queue_walk_unlocked(queue, free_func, cookie);
}
pthread_mutex_unlock(&queue->mutex);
@@ -276,3 +279,40 @@ long uc_thread_queue_length(struct uc_threadqueue *queue)
return length;
}
int uc_thread_queue_clear(struct uc_threadqueue *queue,
uc_thread_queue_walk_func free_func,
void *cookie)
{
if (queue == NULL) {
return -EINVAL;
}
pthread_mutex_lock(&queue->mutex);
//Let the caller free the data
if (free_func != NULL) {
uc_thread_queue_walk_unlocked(queue, free_func, cookie);
}
//reset the elements
queue->first = NULL;
queue->num_elements = 0;
queue->last = &queue->first;
//notify writes, there should be space now
if (queue->num_write_waiters == 1) {
//if there's just one thread waiting to push elements
//use _cond_signal. _cond_broadcast can be more expensive (os dependent)
pthread_cond_signal(&queue->write_cond);
} else if (queue->num_write_waiters > 1) {
//signall all threads that there's items available.
pthread_cond_broadcast(&queue->write_cond);
}
pthread_mutex_unlock(&queue->mutex);
return 0;
}