upiwin/src/msg_queue.c

94 lines
2.1 KiB
C
Raw Normal View History

#include <stdlib.h>
2019-12-01 01:07:37 -07:00
#include <string.h>
#include <pthread.h>
#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;
2019-12-01 01:07:37 -07:00
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;
}
pthread_mutex_unlock(&(queue->mutex));
return rc;
}