Add mq tests; TODO: Find and fix segfault when popping last message;

This commit is contained in:
Nathan Fisher 2023-09-18 10:43:34 -04:00
parent 13d7682861
commit 7ac9d7f973
4 changed files with 73 additions and 9 deletions

View file

@ -59,13 +59,15 @@ struct _mq_node {
typedef struct _mq_node haggis_msg;
typedef struct {
pthread_cond_t *cond;
pthread_cond_t cond;
size_t count;
pthread_mutex_t *mutex;
pthread_mutex_t mutex;
haggis_msg *head;
haggis_msg *tail;
} haggis_mq;
haggis_msg* haggis_msg_init(haggis_message_type tag, haggis_message_body body);
int haggis_mq_init(haggis_mq *mq);
int haggis_mq_push(haggis_mq *queue, haggis_msg *msg);
haggis_msg* haggis_mq_pop(haggis_mq *queue);

25
mq.c
View file

@ -29,6 +29,8 @@
* as such so that the author does not get blamed for bugs
* other than his own.
*/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h> // free, malloc
#include "mq.h"
@ -43,10 +45,19 @@ haggis_msg* haggis_msg_init(haggis_message_type tag, haggis_message_body body) {
return msg;
}
int haggis_mq_push(haggis_mq *queue, haggis_msg *msg) {
msg->next = msg->prev = NULL;
int haggis_mq_init(haggis_mq *mq) {
int ret;
pthread_mutex_lock(queue->mutex);
mq->head = NULL;
mq->tail = NULL;
ret = pthread_mutex_init(&mq->mutex, NULL);
if (ret != 0)
return ret;
return pthread_cond_init(&mq->cond, NULL);
}
int haggis_mq_push(haggis_mq *queue, haggis_msg *msg) {
pthread_mutex_lock(&queue->mutex);
if (queue->tail == NULL) {
queue->tail = queue->head = msg;
} else {
@ -55,7 +66,7 @@ int haggis_mq_push(haggis_mq *queue, haggis_msg *msg) {
queue->tail = msg;
}
queue->count++;
pthread_mutex_unlock(queue->mutex);
pthread_mutex_unlock(&queue->mutex);
return 0;
}
@ -63,8 +74,8 @@ haggis_msg* haggis_mq_pop(haggis_mq *queue) {
haggis_msg *msg;
while (queue->count == 0)
pthread_cond_wait(queue->cond, queue->mutex);
pthread_mutex_lock(queue->mutex);
pthread_cond_wait(&queue->cond, &queue->mutex);
pthread_mutex_lock(&queue->mutex);
queue->count--;
msg = queue->head;
if (msg->tag == EndOfArchive)
@ -74,7 +85,7 @@ haggis_msg* haggis_mq_pop(haggis_mq *queue) {
} else {
queue->head = queue->head->prev;
}
pthread_mutex_unlock(queue->mutex);
pthread_mutex_unlock(&queue->mutex);
msg->prev = msg->next = NULL;
return msg;
}

View file

@ -70,6 +70,7 @@ tests += create_symlink_node
tests += create_fifo_node
tests += create_dev_node
tests += create_file_node
tests += haggis_mq_push_pop
total != echo $(tests) | wc -w | awk '{ print $$1 }'

50
test/haggis_mq_push_pop.c Normal file
View file

@ -0,0 +1,50 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mq.h"
int main() {
haggis_mq mq;
haggis_msg *m1, *m2, *m3, *m4;
haggis_message_type mt1, mt2;
haggis_message_body mb1, mb2;
assert(haggis_mq_init(&mq) == 0);
mt1 = NodeCreated;
mt2 = EndOfArchive;
mb1.f_name = "/bin/cat";
mb2.f_name = NULL;
m1 = haggis_msg_init(mt1, mb1);
assert(m1 != NULL);
assert(m1->next == NULL);
assert(m1->prev == NULL);
assert(m1->tag == NodeCreated);
assert(memcmp(m1->body.f_name, "/bin/cat", 8) == 0);
m2 = haggis_msg_init(mt2, mb2);
assert(m2 != NULL);
assert(m2->next == NULL);
assert(m2->prev == NULL);
assert(m2->tag == EndOfArchive);
assert(m2->body.f_name == NULL);
assert(haggis_mq_push(&mq, m1) == 0);
assert(mq.head->tag == NodeCreated);
assert(mq.tail->tag == NodeCreated);
assert(haggis_mq_push(&mq, m2) == 0);
assert(mq.head->tag == NodeCreated);
assert(mq.tail->tag == EndOfArchive);
m3 = haggis_mq_pop(&mq);
assert(m3->tag == NodeCreated);
assert(memcmp(m3->body.f_name, "/bin/cat", 8) == 0);
free(m3);
/*m4 = haggis_mq_pop(&mq);
assert(m4->tag == EndOfArchive);
assert(mq.head != NULL);*/
}