Skip to content
Extraits de code Groupes Projets
Vérifiée Valider c51194fc rédigé par Kubat's avatar Kubat
Parcourir les fichiers

Thread safe queue

parent 6a1c3cad
Aucune branche associée trouvée
Aucune étiquette associée trouvée
1 requête de fusion!95Process queue
#pragma once #pragma once
#include <pthread.h> #include <pthread.h>
#include <common/common.h>
enum lkt_event_type { enum lkt_event_type {
lkt_event_null = 0, /* NULL */ lkt_event_null = 0, /* NULL */
lkt_event_play_pos = 10, /* size_t */ lkt_event_play_pos = (1 << 1), /* size_t */
lkt_event_play_file = 11, /* const char* */ lkt_event_play_file = (1 << 2), /* const char* */
} type; } type;
#define lkt_event_play (lkt_event_play_pos | lkt_event_play_file)
typedef struct { typedef struct {
unsigned int type; unsigned int type;
void *attr; void *attr;
...@@ -19,6 +22,8 @@ struct queue { ...@@ -19,6 +22,8 @@ struct queue {
volatile lkt_event *contents; volatile lkt_event *contents;
volatile size_t size; volatile size_t size;
volatile size_t last; volatile size_t last;
volatile int available;
}; };
int lkt_queue_new(struct queue *); int lkt_queue_new(struct queue *);
...@@ -26,3 +31,5 @@ void lkt_queue_free(struct queue *); ...@@ -26,3 +31,5 @@ void lkt_queue_free(struct queue *);
void lkt_queue_send(struct queue *, enum lkt_event_type, void *attr); void lkt_queue_send(struct queue *, enum lkt_event_type, void *attr);
lkt_event lkt_queue_handle(struct queue *); lkt_event lkt_queue_handle(struct queue *);
void lkt_queue_make_available(struct queue *, enum lkt_event_type);
...@@ -15,10 +15,13 @@ lkt_queue_new(struct queue *ret) ...@@ -15,10 +15,13 @@ lkt_queue_new(struct queue *ret)
if (!ret) if (!ret)
return 1; return 1;
pthread_mutex_t mxt = PTHREAD_MUTEX_INITIALIZER;
struct queue _ret = { struct queue _ret = {
.contents = malloc(LKT_DEFAULT_LIST_SIZE * sizeof(lkt_event)), .contents = malloc(LKT_DEFAULT_LIST_SIZE * sizeof(lkt_event)),
.size = LKT_DEFAULT_LIST_SIZE, .size = LKT_DEFAULT_LIST_SIZE,
.last = 0, .last = 0,
.available = 0,
.lock = mxt,
}; };
if (_ret.contents == NULL) if (_ret.contents == NULL)
...@@ -31,22 +34,25 @@ lkt_queue_new(struct queue *ret) ...@@ -31,22 +34,25 @@ lkt_queue_new(struct queue *ret)
void void
lkt_queue_free(struct queue *queue) lkt_queue_free(struct queue *queue)
{ {
pthread_mutex_lock(&queue->lock);
if (queue && queue->contents) if (queue && queue->contents)
free((void *) queue->contents); free((void *) queue->contents);
pthread_mutex_unlock(&queue->lock);
} }
void void
lkt_queue_send(struct queue *queue, enum lkt_event_type _type, void *_attr) lkt_queue_send(struct queue *queue, enum lkt_event_type _type, void *_attr)
{ {
pthread_mutex_lock(&queue->lock);
if (!queue) if (!queue)
return; goto end;
volatile lkt_event *new; volatile lkt_event *new;
if (queue->size == queue->last) { if (queue->size == queue->last) {
new = realloc((void *) queue->contents, queue->size * 2 * sizeof(lkt_event)); new = realloc((void *) queue->contents, queue->size * 2 * sizeof(lkt_event));
if (NULL == new) if (NULL == new)
return; goto end;
queue->contents = new; queue->contents = new;
queue->size *= 2; queue->size *= 2;
...@@ -57,17 +63,31 @@ lkt_queue_send(struct queue *queue, enum lkt_event_type _type, void *_attr) ...@@ -57,17 +63,31 @@ lkt_queue_send(struct queue *queue, enum lkt_event_type _type, void *_attr)
.attr = _attr, .attr = _attr,
}; };
queue->contents[(queue->last)++] = evt; queue->contents[(queue->last)++] = evt;
end:
pthread_mutex_unlock(&queue->lock);
} }
lkt_event lkt_event
lkt_queue_handle(struct queue *queue) lkt_queue_handle(struct queue *queue)
{ {
pthread_mutex_lock(&queue->lock);
lkt_event ret = {0}; lkt_event ret = {0};
if (!queue || !queue->last) if (!queue || !queue->last ||
return ret; !(queue->contents[0].type & queue->available))
goto end;
ret = queue->contents[0]; ret = queue->contents[0];
memmove((void *) queue->contents, (void *) (queue->contents + 1), --(queue->last)); memmove((void *) queue->contents, (void *) (queue->contents + 1), --(queue->last));
end:
pthread_mutex_unlock(&queue->lock);
return ret; return ret;
} }
void
lkt_queue_make_available(struct queue *queue, enum lkt_event_type type)
{
pthread_mutex_lock(&queue->lock);
queue->available |= type;
pthread_mutex_unlock(&queue->lock);
}
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter