254 lines
5.1 KiB
C
254 lines
5.1 KiB
C
#include "queue.h"
|
|
|
|
#ifdef _TEST_MODE_
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <strings.h>
|
|
#endif /* _TEST_MODE_ */
|
|
|
|
void queue_init(ht_queue_t *q) {
|
|
q->head = NULL;
|
|
q->tail = NULL;
|
|
|
|
pthread_mutex_init(&q->mutex, NULL);
|
|
|
|
pthread_cond_init(&q->cond, NULL);
|
|
}
|
|
|
|
void queue_destroy(ht_queue_t *q) {
|
|
pthread_mutex_destroy(&q->mutex);
|
|
pthread_cond_destroy(&q->cond);
|
|
}
|
|
|
|
int queue_put(ht_queue_t *q, void *d) {
|
|
queue_entry_t *entry;
|
|
|
|
entry = (queue_entry_t *) malloc(sizeof(queue_entry_t));
|
|
if (NULL == entry)
|
|
return -1;
|
|
|
|
entry->data = d;
|
|
entry->next = NULL;
|
|
entry->prev = NULL;
|
|
|
|
pthread_mutex_lock(&q->mutex);
|
|
|
|
if (NULL != q->tail) {
|
|
entry->next = q->tail;
|
|
q->tail->prev = entry;
|
|
}
|
|
|
|
if (NULL == q->head) {
|
|
q->head = entry;
|
|
}
|
|
|
|
q->tail = entry;
|
|
|
|
pthread_cond_signal(&q->cond);
|
|
pthread_mutex_unlock(&q->mutex);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void *queue_get_wait(ht_queue_t *q) {
|
|
queue_entry_t *entry = NULL;
|
|
void *d = NULL;
|
|
|
|
pthread_mutex_lock(&q->mutex);
|
|
|
|
while ((NULL == q->head) && (NULL == q->tail)) {
|
|
pthread_cond_wait(&q->cond, &q->mutex);
|
|
}
|
|
|
|
entry = q->head;
|
|
|
|
if (NULL != q->head) {
|
|
q->head = q->head->prev;
|
|
}
|
|
|
|
if (NULL == q->head) {
|
|
q->tail = NULL;
|
|
} else {
|
|
q->head->next = NULL;
|
|
}
|
|
|
|
if (NULL != entry) {
|
|
d = entry->data;
|
|
free(entry);
|
|
}
|
|
|
|
pthread_mutex_unlock(&q->mutex);
|
|
|
|
return d;
|
|
}
|
|
|
|
|
|
#ifdef _TEST_MODE_
|
|
|
|
#define TEST_STRING_1 "test1"
|
|
#define TEST_STRING_2 "test2"
|
|
#define TEST_STRING_3 "test2"
|
|
|
|
int main(int argc, char **argv) {
|
|
ht_queue_t q;
|
|
char *s;
|
|
|
|
printf("queue test\n");
|
|
|
|
printf("\none-item queue: put, get\n");
|
|
queue_init(&q);
|
|
|
|
if (0 != queue_put(&q, (void*)TEST_STRING_1)) {
|
|
printf("- queue_put failed\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_put passed\n");
|
|
|
|
s = (char*) queue_get_wait(&q);
|
|
|
|
if (0 != strcmp(s, TEST_STRING_1)) {
|
|
printf("- queue_get_wait returned something wrong\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_get_wait for one-item queue passed\n");
|
|
|
|
queue_destroy(&q);
|
|
|
|
|
|
printf("\ntwo-item queue: put, put, get, get\n");
|
|
queue_init(&q);
|
|
|
|
if (0 != queue_put(&q, (void*)TEST_STRING_1)) {
|
|
printf("- queue_put failed\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_put passed\n");
|
|
|
|
if (0 != queue_put(&q, (void*)TEST_STRING_2)) {
|
|
printf("- queue_put failed\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_put passed\n");
|
|
|
|
s = (char*) queue_get_wait(&q);
|
|
|
|
if (0 != strcmp(s, TEST_STRING_1)) {
|
|
printf("- queue_get_wait returned something wrong\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_get_wait (first) for two-item queue passed\n");
|
|
|
|
s = (char*) queue_get_wait(&q);
|
|
|
|
if (0 != strcmp(s, TEST_STRING_2)) {
|
|
printf("- queue_get_wait returned something wrong\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_get_wait (second) for two-item queue passed\n");
|
|
|
|
queue_destroy(&q);
|
|
|
|
|
|
printf("\nthree-item queue: put, put, put, get, get, get\n");
|
|
queue_init(&q);
|
|
|
|
if (0 != queue_put(&q, (void*)TEST_STRING_1)) {
|
|
printf("- queue_put failed\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_put passed\n");
|
|
|
|
if (0 != queue_put(&q, (void*)TEST_STRING_2)) {
|
|
printf("- queue_put failed\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_put passed\n");
|
|
|
|
if (0 != queue_put(&q, (void*)TEST_STRING_3)) {
|
|
printf("- queue_put failed\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_put passed\n");
|
|
|
|
s = (char*) queue_get_wait(&q);
|
|
|
|
if (0 != strcmp(s, TEST_STRING_1)) {
|
|
printf("- queue_get_wait returned something wrong\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_get_wait (first) for three-item queue passed\n");
|
|
|
|
s = (char*) queue_get_wait(&q);
|
|
|
|
if (0 != strcmp(s, TEST_STRING_2)) {
|
|
printf("- queue_get_wait returned something wrong\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_get_wait (second) for three-item queue passed\n");
|
|
|
|
s = (char*) queue_get_wait(&q);
|
|
|
|
if (0 != strcmp(s, TEST_STRING_3)) {
|
|
printf("- queue_get_wait returned something wrong\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_get_wait (third) for three-item queue passed\n");
|
|
|
|
queue_destroy(&q);
|
|
|
|
|
|
printf("\nthree-item queue, different sequence: put, get, put, put, get, get\n");
|
|
queue_init(&q);
|
|
|
|
if (0 != queue_put(&q, (void*)TEST_STRING_1)) {
|
|
printf("- queue_put failed\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_put passed\n");
|
|
|
|
s = (char*) queue_get_wait(&q);
|
|
|
|
if (0 != strcmp(s, TEST_STRING_1)) {
|
|
printf("- queue_get_wait returned something wrong\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_get_wait (first) for three-item queue passed\n");
|
|
|
|
if (0 != queue_put(&q, (void*)TEST_STRING_2)) {
|
|
printf("- queue_put failed\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_put passed\n");
|
|
|
|
if (0 != queue_put(&q, (void*)TEST_STRING_3)) {
|
|
printf("- queue_put failed\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_put passed\n");
|
|
|
|
s = (char*) queue_get_wait(&q);
|
|
|
|
if (0 != strcmp(s, TEST_STRING_2)) {
|
|
printf("- queue_get_wait returned something wrong\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_get_wait (second) for three-item queue passed\n");
|
|
|
|
s = (char*) queue_get_wait(&q);
|
|
|
|
if (0 != strcmp(s, TEST_STRING_3)) {
|
|
printf("- queue_get_wait returned something wrong\n");
|
|
exit(1);
|
|
}
|
|
printf("+ queue_get_wait (third) for three-item queue passed\n");
|
|
|
|
queue_destroy(&q);
|
|
|
|
|
|
|
|
exit(0);
|
|
}
|
|
|
|
|
|
#endif /* _TEST_MODE_ */
|