More threadqueue docs & tests
This commit is contained in:
+9
-43
@@ -8,43 +8,14 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
/**
|
/**
|
||||||
* @defgroup ThreadQueue ThreadQueue
|
* @defgroup ThreadQueue ThreadQueue
|
||||||
|
* @{
|
||||||
*
|
*
|
||||||
* Little API for waitable queues, typically used for passing messages
|
* Little API for waitable queues, typically used for passing messages
|
||||||
* between threads.
|
* between threads.
|
||||||
*
|
*
|
||||||
* @author Nils O. Selåsdal <NOS@Utel.no>
|
* @author Nils O. Selåsdal <NOS@Utel.no>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @mainpage
|
|
||||||
* @htmlonly
|
|
||||||
* <pre>
|
|
||||||
* Copyright (c) 2002-2003 Nils O. Selåsdal <NOS@Utel.no>.
|
|
||||||
* All rights reserved, all wrongs reversed.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
* </pre>
|
|
||||||
* @endhtmlonly
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A thread message used to add and retrieve messages
|
* A thread message used to add and retrieve messages
|
||||||
@@ -70,13 +41,15 @@ struct uc_threadmsg{
|
|||||||
struct uc_threadmsg *next;
|
struct uc_threadmsg *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback function for the walk and destroy functions.
|
||||||
|
*/
|
||||||
typedef void (*uc_thread_queue_walk_func) (struct uc_threadmsg *msg);
|
typedef void (*uc_thread_queue_walk_func) (struct uc_threadmsg *msg);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A ThreadQueue
|
* A ThreadQueue
|
||||||
*
|
*
|
||||||
* @ingroup ThreadQueue
|
|
||||||
*
|
*
|
||||||
* You should threat this struct as opaque never ever access any of
|
* You should threat this struct as opaque never ever access any of
|
||||||
* the variables in this struct.
|
* the variables in this struct.
|
||||||
@@ -161,8 +134,6 @@ struct uc_threadqueue {
|
|||||||
/**
|
/**
|
||||||
* Initializes a queue.
|
* Initializes a queue.
|
||||||
*
|
*
|
||||||
* @ingroup ThreadQueue
|
|
||||||
*
|
|
||||||
* thread_queue_init initializes a new threadqueue. A new queue must always
|
* thread_queue_init initializes a new threadqueue. A new queue must always
|
||||||
* be initialized before it is used.
|
* be initialized before it is used.
|
||||||
* A max number of elements the queue will hold must be given.
|
* A max number of elements the queue will hold must be given.
|
||||||
@@ -180,8 +151,6 @@ int uc_thread_queue_init(struct uc_threadqueue *queue, long max_elements);
|
|||||||
/**
|
/**
|
||||||
* Adds a message to a queue
|
* Adds a message to a queue
|
||||||
*
|
*
|
||||||
* @ingroup ThreadQueue
|
|
||||||
*
|
|
||||||
* thread_queue_add adds a "message" to the specified queue.
|
* thread_queue_add adds a "message" to the specified queue.
|
||||||
* It is up to the application to manage the data and memory indicated by the
|
* It is up to the application to manage the data and memory indicated by the
|
||||||
* struct uc_threadmsg.
|
* struct uc_threadmsg.
|
||||||
@@ -206,10 +175,8 @@ int uc_thread_queue_add(struct uc_threadqueue *queue, struct uc_threadmsg *msg);
|
|||||||
/**
|
/**
|
||||||
* Gets a message from a queue
|
* Gets a message from a queue
|
||||||
*
|
*
|
||||||
* @ingroup ThreadQueue
|
|
||||||
*
|
|
||||||
* thread_queue_get gets a message from the specified queue, it will block
|
* thread_queue_get gets a message from the specified queue, it will block
|
||||||
* the caøling thread untill a message arrives, or the (optional) timeout occurs.
|
* the caling thread untill a message arrives, or the (optional) timeout occurs.
|
||||||
* If timeout is NULL, there will be no timeout, and thread_queue_get will wait
|
* If timeout is NULL, there will be no timeout, and thread_queue_get will wait
|
||||||
* untill a message arrives.
|
* untill a message arrives.
|
||||||
*
|
*
|
||||||
@@ -233,8 +200,6 @@ int uc_thread_queue_get(struct uc_threadqueue *queue, const struct timespec *tim
|
|||||||
/**
|
/**
|
||||||
* Gets the length of a queue
|
* Gets the length of a queue
|
||||||
*
|
*
|
||||||
* @ingroup ThreadQueue
|
|
||||||
*
|
|
||||||
* threadqueue_length returns the number of messages waiting in the queue
|
* threadqueue_length returns the number of messages waiting in the queue
|
||||||
*
|
*
|
||||||
* @param queue Pointer to the queue for which to get the length
|
* @param queue Pointer to the queue for which to get the length
|
||||||
@@ -243,7 +208,6 @@ int uc_thread_queue_get(struct uc_threadqueue *queue, const struct timespec *tim
|
|||||||
long uc_thread_queue_length( struct uc_threadqueue *queue );
|
long uc_thread_queue_length( struct uc_threadqueue *queue );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup ThreadQueue
|
|
||||||
* Destroy the queue.
|
* Destroy the queue.
|
||||||
*
|
*
|
||||||
* If free_func is != NULL, free_func will be called for every item, allowing you to free
|
* If free_func is != NULL, free_func will be called for every item, allowing you to free
|
||||||
@@ -261,7 +225,6 @@ long uc_thread_queue_length( struct uc_threadqueue *queue );
|
|||||||
int uc_thread_queue_destroy(struct uc_threadqueue *queue, uc_thread_queue_walk_func free_func);
|
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
|
* Walk the elements of the queue, intended for debugging
|
||||||
*
|
*
|
||||||
* The supplied function will be called for each item in the queue, internal queue
|
* The supplied function will be called for each item in the queue, internal queue
|
||||||
@@ -275,6 +238,9 @@ int uc_thread_queue_destroy(struct uc_threadqueue *queue, uc_thread_queue_walk_f
|
|||||||
*/
|
*/
|
||||||
int uc_thread_queue_walk(struct uc_threadqueue *queue, uc_thread_queue_walk_func walk_func);
|
int uc_thread_queue_walk(struct uc_threadqueue *queue, uc_thread_queue_walk_func walk_func);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <check.h>
|
#include <check.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "ucore_threadqueue.h"
|
#include "ucore_threadqueue.h"
|
||||||
@@ -198,6 +199,53 @@ START_TEST (test_thread_queue_multiple_writers)
|
|||||||
|
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_thread_queue_timeout1)
|
||||||
|
|
||||||
|
struct uc_threadqueue queue;
|
||||||
|
struct timespec timeout = {0, 1000};
|
||||||
|
struct uc_threadmsg *msg;
|
||||||
|
|
||||||
|
fail_if(uc_thread_queue_init(&queue, 100) != 0);
|
||||||
|
|
||||||
|
fail_if(uc_thread_queue_get(&queue, &timeout, &msg) != ETIMEDOUT);
|
||||||
|
uc_thread_queue_destroy(&queue, NULL);
|
||||||
|
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
void *thread_test_thread_queue_timeout2(void *arg)
|
||||||
|
{
|
||||||
|
struct uc_threadqueue *queue = arg;
|
||||||
|
struct uc_threadmsg *msg;
|
||||||
|
struct thr_msg *my_msg;
|
||||||
|
struct timespec timeout = {0, 2000};
|
||||||
|
|
||||||
|
fail_if(uc_thread_queue_get(queue, &timeout, &msg) != 0);
|
||||||
|
fail_if(uc_thread_queue_get(queue, &timeout, &msg) != ETIMEDOUT);
|
||||||
|
|
||||||
|
my_msg = (struct thr_msg *)msg;
|
||||||
|
fail_if(my_msg->b != 12345);
|
||||||
|
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
START_TEST (test_thread_queue_timeout2)
|
||||||
|
|
||||||
|
struct uc_threadqueue queue;
|
||||||
|
pthread_t tid1;
|
||||||
|
struct thr_msg my_msg;
|
||||||
|
|
||||||
|
fail_if(uc_thread_queue_init(&queue, 10) != 0);
|
||||||
|
fail_if(pthread_create(&tid1, NULL, thread_test_thread_queue_timeout2, &queue) != 0);
|
||||||
|
my_msg.b = 12345;
|
||||||
|
fail_if(uc_thread_queue_add(&queue, &my_msg.msg) != 0);
|
||||||
|
|
||||||
|
|
||||||
|
pthread_join(tid1, NULL);
|
||||||
|
|
||||||
|
uc_thread_queue_destroy(&queue, NULL);
|
||||||
|
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
|
||||||
Suite *threadqueue_suite(void)
|
Suite *threadqueue_suite(void)
|
||||||
{
|
{
|
||||||
@@ -211,6 +259,8 @@ Suite *threadqueue_suite(void)
|
|||||||
tcase_add_test(tc1, test_thread_queue_reader_writer_len_1);
|
tcase_add_test(tc1, test_thread_queue_reader_writer_len_1);
|
||||||
tcase_add_test(tc1, test_thread_queue_zero_len);
|
tcase_add_test(tc1, test_thread_queue_zero_len);
|
||||||
tcase_add_test(tc1, test_thread_queue_multiple_writers);
|
tcase_add_test(tc1, test_thread_queue_multiple_writers);
|
||||||
|
tcase_add_test(tc1, test_thread_queue_timeout1);
|
||||||
|
tcase_add_test(tc1, test_thread_queue_timeout2);
|
||||||
|
|
||||||
//lets start with this:
|
//lets start with this:
|
||||||
tcase_set_timeout(tc1, 15);
|
tcase_set_timeout(tc1, 15);
|
||||||
|
|||||||
Reference in New Issue
Block a user