Introduce walk_func

This commit is contained in:
Nils O. Selåsdal
2012-11-12 21:21:57 +01:00
parent 5a7bc1b078
commit ac83766abc
2 changed files with 51 additions and 14 deletions
+29 -8
View File
@@ -149,8 +149,33 @@ int uc_thread_queue_get(struct uc_threadqueue *queue, const struct timespec *tim
return 0; return 0;
} }
static void uc_thread_queue_walk_unlocled(struct uc_threadqueue *queue, uc_thread_queue_walk_func walk_func)
{
struct uc_threadmsg *p;
struct uc_threadmsg *next;
for(p = queue->first; p; p = next) {
next = p->next;
walk_func(p);
}
}
int uc_thread_queue_walk(struct uc_threadqueue *queue, uc_thread_queue_walk_func walk_func)
{
if (queue == NULL || !walk_func) {
return EINVAL;
}
pthread_mutex_lock(&queue->mutex);
uc_thread_queue_walk_unlocled(queue, walk_func);
pthread_mutex_unlock(&queue->mutex);
return 0;
}
//maybe caller should supply a callback for cleaning the elements ? //maybe caller should supply a callback for cleaning the elements ?
int uc_thread_queue_cleanup(struct uc_threadqueue *queue, int freedata) int uc_thread_queue_cleanup(struct uc_threadqueue *queue, uc_thread_queue_walk_func free_func)
{ {
int rc; int rc;
@@ -172,13 +197,8 @@ int uc_thread_queue_cleanup(struct uc_threadqueue *queue, int freedata)
return EBUSY; return EBUSY;
} }
if(freedata) { if(free_func) {
struct uc_threadmsg *p; uc_thread_queue_walk_unlocled(queue, free_func);
struct uc_threadmsg *next;
for(p = queue->first; p; p = next) {
next = p->next;
free(p);
}
} }
pthread_mutex_unlock(&queue->mutex); pthread_mutex_unlock(&queue->mutex);
@@ -190,6 +210,7 @@ int uc_thread_queue_cleanup(struct uc_threadqueue *queue, int freedata)
} }
long thread_queue_length(struct uc_threadqueue *queue) long thread_queue_length(struct uc_threadqueue *queue)
{ {
long length; long length;
+22 -6
View File
@@ -70,6 +70,8 @@ struct uc_threadmsg{
struct uc_threadmsg *next; struct uc_threadmsg *next;
}; };
typedef int (*uc_thread_queue_walk_func) (struct uc_threadmsg *msg);
/** /**
* A ThreadQueue * A ThreadQueue
@@ -242,22 +244,36 @@ long uc_thread_queue_length( struct uc_threadqueue *queue );
/** /**
* @ingroup ThreadQueue * @ingroup ThreadQueue
* Destroy a queue.
*
* Destroy the queue. * Destroy the queue.
* *
* If freedata is != 0 free(3) will be called on all pending messages in the queue * If free_func is != NULL, free_func will be called for every item, allowing you to free
* the item.
* You cannot call this if there are someone currently adding or getting messages * You cannot call this if there are someone currently adding or getting messages
* from the queue. * from the queue.
* After a queue have been cleaned, it cannot be used again untill #thread_queue_init * After a queue have been cleaned, it cannot be used again untill #thread_queue_init
* has been called on the queue. * has been called on the queue.
* *
* @param queue Pointer to the queue that should be cleaned * @param queue Pointer to the queue that should be cleaned
* @param freedata set to nonzero if free(3) should be called on remaining * @param free_func pointer to function that will be called for each item.
* messages * The function must not in anyway interact with the queue.
* @return 0 on success EINVAL if queue is NULL EBUSY if someone is holding any locks on the queue * @return 0 on success EINVAL if queue is NULL EBUSY if someone is holding any locks on the queue
*/ */
int uc_thread_queue_destroy(struct uc_threadqueue *queue, int freedata); int uc_thread_queue_destroy(struct uc_threadqueue *queue, uc_thread_queue_walk_func free_func);
/**
* @ingroup ThreadQueue
* Walk the elements of the queue, intended for debugging
*
* The supplied function will be called for each item in the queue, internal queue
* locks are held while the function is called, so the supplied function must not
* interact with the queue, else deadlock occors.
*
* @param queue Pointer to the queue to walk
* @param free_func pointer to function that will be called for each item.
* The function must not in anyway interact with the queue.
* @return 0 on success
*/
int uc_thread_queue_walk(struct uc_threadqueue *queue, uc_thread_queue_walk_func walk_func);
#ifdef __cplusplus #ifdef __cplusplus
} }