summaryrefslogtreecommitdiff
path: root/handler.c
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2012-11-25 22:08:22 +0100
committerGravatar waker <wakeroid@gmail.com>2012-11-25 22:08:22 +0100
commitb77b07311b729449e3c2d78741c4b0643fae6fad (patch)
treefe5a0c7ea0258fad24e4e4fbf286ef409de19939 /handler.c
parent11a09631a9023ac73eaa8325c84f9343d253c279 (diff)
added new generic message queue module
Diffstat (limited to 'handler.c')
-rw-r--r--handler.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/handler.c b/handler.c
new file mode 100644
index 00000000..e561f43e
--- /dev/null
+++ b/handler.c
@@ -0,0 +1,143 @@
+/*
+ This file is part of Deadbeef Player source code
+ http://deadbeef.sourceforge.net
+
+ generic message queue implementation
+
+ Copyright (C) 2009-2012 Alexey Yakovenko
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Alexey Yakovenko waker@users.sourceforge.net
+*/
+#include "handler.h"
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include "handler.h"
+#include "threading.h"
+
+typedef struct message_s {
+ uint32_t id;
+ uintptr_t ctx;
+ uint32_t p1;
+ uint32_t p2;
+ struct message_s *next;
+} message_t;
+
+typedef struct handler_s {
+ int queue_size;
+ message_t pool[1];
+ message_t *mfree;
+ message_t *mqueue;
+ message_t *mqtail;
+ uintptr_t mutex;
+ uintptr_t cond;
+} handler_t;
+
+static void
+handler_reset (handler_t *h) {
+ h->mqueue = NULL;
+ h->mfree = NULL;
+ h->mqtail = NULL;
+ memset (h->pool, 0, sizeof (message_t) * h->queue_size);
+ for (int i = 0; i < h->queue_size; i++) {
+ h->pool[i].next = h->mfree;
+ h->mfree = &h->pool[i];
+ }
+}
+
+handler_t *
+handler_alloc (int queue_size) {
+ int sz = sizeof (handler_t) + (queue_size-1) * sizeof (message_t);
+ handler_t *h = malloc (sz);
+ memset (h, 0, sz);
+ h->mutex = mutex_create ();
+ h->cond = cond_create ();
+ return h;
+}
+
+void
+handler_free (handler_t *h) {
+ mutex_lock (h->mutex);
+ handler_reset (h);
+ mutex_unlock (h->mutex);
+ mutex_free (h->mutex);
+ cond_free (h->cond);
+ free (h);
+}
+
+int
+handler_push (handler_t *h, uint32_t id, uintptr_t ctx, uint32_t p1, uint32_t p2) {
+ if (!h->mfree) {
+ return -1;
+ }
+ mutex_lock (h->mutex);
+ message_t *msg = h->mfree;
+ h->mfree = h->mfree->next;
+ if (h->mqtail) {
+ h->mqtail->next = msg;
+ }
+ h->mqtail = msg;
+ if (!h->mqueue) {
+ h->mqueue = msg;
+ }
+
+ msg->next = NULL;
+ msg->id = id;
+ msg->ctx = ctx;
+ msg->p1 = p1;
+ msg->p2 = p2;
+ mutex_unlock (h->mutex);
+ cond_signal (h->cond);
+ return 0;
+}
+
+void
+handler_wait (handler_t *h) {
+ cond_wait (h->cond, h->mutex);
+ mutex_unlock (h->mutex);
+}
+
+int
+handler_pop (handler_t *h, uint32_t *id, uintptr_t *ctx, uint32_t *p1, uint32_t *p2) {
+ mutex_lock (h->mutex);
+ if (!h->mqueue) {
+ mutex_unlock (h->mutex);
+ return -1;
+ }
+ *id = h->mqueue->id;
+ *ctx = h->mqueue->ctx;
+ *p1 = h->mqueue->p1;
+ *p2 = h->mqueue->p2;
+ message_t *next = h->mqueue->next;
+ h->mqueue->next = h->mfree;
+ h->mfree = h->mqueue;
+ h->mqueue = next;
+ if (!h->mqueue) {
+ h->mqtail = NULL;
+ }
+ mutex_unlock (h->mutex);
+ return 0;
+}
+
+int
+handler_hasmessages (handler_t *h) {
+ return h->mqueue ? 1 : 0;
+}
+