#include #include #include #include "wintype.h" #include "time_func.h" #include "msg_queue.h" PMSG_QUEUE MqAlloc(int nentries) { int sz = sizeof(MSG_QUEUE) + (nentries * sizeof(MSG)); PMSG_QUEUE rc; rc = (PMSG_QUEUE)malloc(sz); if (!rc) return NULL; memset(rc, 0, sz); rc->startbound = &(rc->messagestore[0]); rc->endbound = rc->startbound + nentries; rc->head = rc->tail = rc->startbound; rc->nentries = nentries; pthread_mutex_init(&(rc->mutex), NULL); return rc; } void MqDestroy(PMSG_QUEUE queue) { pthread_mutex_destroy(&(queue->mutex)); free(queue); } static void post_internal(PMSG_QUEUE queue, PMSG msg) { PMSG nexttail; pthread_mutex_lock(&(queue->mutex)); nexttail = queue->tail + 1; if (nexttail == queue->endbound) nexttail = queue->startbound; if (nexttail != queue->head) { memcpy(queue->tail, msg, sizeof(MSG)); queue->tail = nexttail; } /* else drop the message silently */ pthread_mutex_unlock(&(queue->mutex)); } void MqPost(PMSG_QUEUE queue, uintptr_t target, unsigned message, const uintptr_t *attrs, int nattrs) { MSG tmpmsg; memset(&tmpmsg, 0, sizeof(MSG)); tmpmsg.target = target; tmpmsg.message = message; if (nattrs > MSG_ATTRCOUNT) nattrs = MSG_ATTRCOUNT; if (nattrs > 0) memcpy(&(tmpmsg.attrs), attrs, sizeof(uintptr_t) * nattrs); tmpmsg.timestamp = TimeSinceStart(); post_internal(queue, &tmpmsg); } void MqPost1(PMSG_QUEUE queue, uintptr_t target, unsigned message, uintptr_t attr1) { MSG tmpmsg; memset(&tmpmsg, 0, sizeof(MSG)); tmpmsg.target = target; tmpmsg.message = message; tmpmsg.attrs[0] = attr1; tmpmsg.timestamp = TimeSinceStart(); post_internal(queue, &tmpmsg); } int MqPeek(PMSG_QUEUE queue, PMSG msg, unsigned flags) { int rc = 0; PMSG nexthead; pthread_mutex_lock(&(queue->mutex)); if (queue->head != queue->tail) { nexthead = queue->head + 1; if (nexthead == queue->endbound) nexthead = queue->startbound; memcpy(msg, queue->head, sizeof(MSG)); if (flags & PEEK_REMOVE) queue->head = nexthead; rc = 1; } pthread_mutex_unlock(&(queue->mutex)); return rc; }