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:
+46
-6
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user