Initial commit
This commit is contained in:
2
lib/asyncmsg/Makefile
Normal file
2
lib/asyncmsg/Makefile
Normal file
@@ -0,0 +1,2 @@
|
||||
LIST=CPU
|
||||
include recurse.mk
|
||||
107
lib/asyncmsg/_asyncmsg_handle.c
Normal file
107
lib/asyncmsg/_asyncmsg_handle.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include "asyncmsg_priv.h"
|
||||
|
||||
#define _ASYNCMSG_HANDLE_LIST_GROW 4
|
||||
|
||||
struct _asyncmsg_handle_list {
|
||||
pthread_rwlock_t rwlock;
|
||||
void **array;
|
||||
int array_total;
|
||||
};
|
||||
|
||||
static struct _asyncmsg_handle_list _channel_list = {
|
||||
PTHREAD_RWLOCK_INITIALIZER, 0, 0
|
||||
};
|
||||
|
||||
static struct _asyncmsg_handle_list _fd_list = {
|
||||
PTHREAD_RWLOCK_INITIALIZER, 0, 0
|
||||
};
|
||||
|
||||
static struct _asyncmsg_handle_list _connect_list = {
|
||||
PTHREAD_RWLOCK_INITIALIZER, 0, 0
|
||||
};
|
||||
|
||||
void * _asyncmsg_handle(int id, int cmd, void *handle)
|
||||
{
|
||||
struct _asyncmsg_handle_list *list;
|
||||
|
||||
if (cmd & _ASYNCMSG_HANDLE_CHANNEL) {
|
||||
cmd &= ~_ASYNCMSG_HANDLE_CHANNEL;
|
||||
list = &_channel_list;
|
||||
} else if (id & _NTO_SIDE_CHANNEL) {
|
||||
list = &_connect_list;
|
||||
id &= ~_NTO_SIDE_CHANNEL;
|
||||
} else {
|
||||
list = &_fd_list;
|
||||
}
|
||||
|
||||
if (cmd == _ASYNCMSG_HANDLE_ADD) {
|
||||
if ((errno = pthread_rwlock_wrlock(&list->rwlock)) != EOK) {
|
||||
return NULL;
|
||||
}
|
||||
if (list->array_total <= id) {
|
||||
void **new_array;
|
||||
size_t new_size;
|
||||
int extra;
|
||||
|
||||
|
||||
if ((extra = id - list->array_total + 1) < _ASYNCMSG_HANDLE_LIST_GROW)
|
||||
extra = _ASYNCMSG_HANDLE_LIST_GROW;
|
||||
new_size = (list->array_total + extra) * sizeof(void *);
|
||||
if ((new_array = realloc(list->array, new_size)) == NULL) {
|
||||
pthread_rwlock_unlock(&list->rwlock);
|
||||
return NULL;
|
||||
}
|
||||
memset(&new_array[list->array_total], 0, extra * sizeof(void *));
|
||||
list->array = new_array;
|
||||
list->array_total += extra;
|
||||
}
|
||||
list->array[id] = handle;
|
||||
pthread_rwlock_unlock(&list->rwlock);
|
||||
return handle;
|
||||
}
|
||||
|
||||
if (id >= list->array_total) {
|
||||
errno = ESRCH;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((errno = pthread_rwlock_rdlock(&list->rwlock)) != EOK) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
handle = list->array[id];
|
||||
if (cmd & _ASYNCMSG_HANDLE_DELETE) {
|
||||
list->array[id] = NULL;
|
||||
}
|
||||
pthread_rwlock_unlock(&list->rwlock);
|
||||
|
||||
if (!handle)
|
||||
errno = ESRCH;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
__SRCVERSION("_asyncmsg_handle.c $Rev: 157149 $");
|
||||
8
lib/asyncmsg/arm/Makefile
Normal file
8
lib/asyncmsg/arm/Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
LIST=VARIANT
|
||||
ifndef QRECURSE
|
||||
QRECURSE=recurse.mk
|
||||
ifdef QCONFIG
|
||||
QRDIR=$(dir $(QCONFIG))
|
||||
endif
|
||||
endif
|
||||
include $(QRDIR)$(QRECURSE)
|
||||
1
lib/asyncmsg/arm/a.be/Makefile
Normal file
1
lib/asyncmsg/arm/a.be/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
include ../../common.mk
|
||||
1
lib/asyncmsg/arm/a.le/Makefile
Normal file
1
lib/asyncmsg/arm/a.le/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
include ../../common.mk
|
||||
1
lib/asyncmsg/arm/so.be/Makefile
Normal file
1
lib/asyncmsg/arm/so.be/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
include ../../common.mk
|
||||
1
lib/asyncmsg/arm/so.le/Makefile
Normal file
1
lib/asyncmsg/arm/so.le/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
include ../../common.mk
|
||||
69
lib/asyncmsg/asyncmsg_channel_create.c
Normal file
69
lib/asyncmsg/asyncmsg_channel_create.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include "asyncmsg_priv.h"
|
||||
|
||||
/* This is painful. We have to prepare receive buf, and associate
|
||||
* it with the chid, so we will know where to receive
|
||||
*/
|
||||
int asyncmsg_channel_create(unsigned flags, mode_t mode, size_t buffer_size, unsigned max_num_buffer, const struct sigevent *ev, int (*recvbuf_callback)(size_t bufsize, unsigned num_bufs, void*bufs[], int flags))
|
||||
{
|
||||
struct _asyncmsg_channel_context *acc;
|
||||
int chid;
|
||||
|
||||
if ((acc = (struct _asyncmsg_channel_context *)malloc(sizeof(*acc))) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
memset(acc, 0, sizeof(*acc));
|
||||
|
||||
if ((errno = pthread_mutex_init(&acc->mutex, 0)) != EOK) {
|
||||
free(acc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
acc->recvbuf_cb = recvbuf_callback;
|
||||
acc->max_num_buffer = max_num_buffer;
|
||||
acc->buffer_size = buffer_size;
|
||||
|
||||
if ((acc->iovs = malloc(sizeof(iov_t) * max_num_buffer)) == NULL) {
|
||||
free(acc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((chid = ChannelCreateExt(flags | _NTO_CHF_ASYNC, mode, buffer_size, max_num_buffer, ev, NULL)) == -1) {
|
||||
pthread_mutex_destroy(&acc->mutex);
|
||||
free(acc->iovs);
|
||||
free(acc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_asyncmsg_handle(chid, _ASYNCMSG_HANDLE_ADD | _ASYNCMSG_HANDLE_CHANNEL, acc) == NULL) {
|
||||
asyncmsg_channel_destroy(chid);
|
||||
free(acc->iovs);
|
||||
free(acc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return chid;
|
||||
}
|
||||
|
||||
__SRCVERSION("asyncmsg_channel_create.c $Rev: 153052 $");
|
||||
75
lib/asyncmsg/asyncmsg_channel_destroy.c
Normal file
75
lib/asyncmsg/asyncmsg_channel_destroy.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "asyncmsg_priv.h"
|
||||
|
||||
int asyncmsg_channel_destroy(int chid)
|
||||
{
|
||||
struct _asyncmsg_channel_context *acc;
|
||||
|
||||
if (ChannelDestroy(chid) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((acc = _asyncmsg_handle(chid, _ASYNCMSG_HANDLE_DELETE | _ASYNCMSG_HANDLE_CHANNEL, 0)) == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* how do we destroy mutex safely ? */
|
||||
pthread_mutex_destroy(&acc->mutex);
|
||||
|
||||
if (acc->free) {
|
||||
if (!acc->recvbuf_cb) {
|
||||
struct _asyncmsg_get_header *ahp;
|
||||
|
||||
while (ahp = acc->free) {
|
||||
acc->free = ahp->next;
|
||||
asyncmsg_free(ahp);
|
||||
}
|
||||
} else {
|
||||
int i, n;
|
||||
void **buffs, *single_buf;
|
||||
|
||||
if ((buffs = alloca(acc->num_free * sizeof(void *))) == NULL) {
|
||||
buffs = &single_buf;
|
||||
n = 1;
|
||||
} else {
|
||||
n = acc->num_free;
|
||||
}
|
||||
|
||||
do {
|
||||
for (i = 0; i < n; i++) {
|
||||
buffs[i] = acc->free;
|
||||
acc->free = acc->free->next;
|
||||
}
|
||||
acc->recvbuf_cb(acc->buffer_size + sizeof(iov_t) + sizeof(struct _asyncmsg_get_header),
|
||||
n, buffs, ASYNCMSG_RECVBUF_FREE);
|
||||
acc->num_free -= n;
|
||||
} while (acc->num_free);
|
||||
}
|
||||
}
|
||||
free(acc->iovs);
|
||||
free(acc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__SRCVERSION("asyncmsg_channel_destroy.c $Rev: 153052 $");
|
||||
181
lib/asyncmsg/asyncmsg_connect_attach.c
Normal file
181
lib/asyncmsg/asyncmsg_connect_attach.c
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "asyncmsg_priv.h"
|
||||
|
||||
static struct sigevent *_async_ev;
|
||||
static pthread_t _async_ev_tid;
|
||||
|
||||
static void * _async_event_thread(void *arg)
|
||||
{
|
||||
int chid = (int)arg, coid;
|
||||
struct _pulse pulse;
|
||||
struct _asyncmsg_connect_context *acc;
|
||||
struct _asyncmsg_connection_descriptor *acd;
|
||||
|
||||
for (;;) {
|
||||
if (MsgReceivePulse(chid, &pulse, sizeof(pulse), NULL) == -1)
|
||||
return NULL;
|
||||
|
||||
coid = pulse.value.sival_int;
|
||||
if ((acc = _asyncmsg_handle(coid, _ASYNCMSG_HANDLE_LOOKUP, 0)) == NULL)
|
||||
continue;
|
||||
acd = &acc->acd;
|
||||
|
||||
_mutex_lock(&acd->mu);
|
||||
if (pulse.code == 'T') {
|
||||
/* triger timer expired */
|
||||
if (acc->acd.num_curmsg) {
|
||||
MsgSendAsync(coid);
|
||||
}
|
||||
acc->flags |= _ASYNCMSG_CONNECT_TIMEROFF;
|
||||
_mutex_unlock(&acd->mu);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pulse.code == 'P')
|
||||
{
|
||||
/* collect some done message from "free" ptr */
|
||||
struct _asyncmsg_put_header *aph;
|
||||
|
||||
while (acd->sendq_free != acd->sendq_head) {
|
||||
aph = &acd->sendq[acd->sendq_free];
|
||||
if (aph->cb) {
|
||||
aph->cb(aph->err, aph->iov, aph->handle);
|
||||
} else if (acd->attr.call_back) {
|
||||
acd->attr.call_back(aph->err, aph->iov, aph->handle);
|
||||
}
|
||||
|
||||
if (++acd->sendq_free >= acd->sendq_size)
|
||||
acd->sendq_free = 0;
|
||||
}
|
||||
|
||||
/* Sigh! have to use broadcast cause the condvar both
|
||||
* use for queue full, and asyncmsg_flush()
|
||||
*/
|
||||
pthread_cond_broadcast(&acd->block_con);
|
||||
_mutex_unlock(&acd->mu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int asyncmsg_connect_attach(uint32_t nd, pid_t pid, int chid, unsigned index, unsigned flags, const struct _asyncmsg_connection_attr *attr)
|
||||
{
|
||||
struct _asyncmsg_connect_context *acc;
|
||||
struct _asyncmsg_connection_descriptor *acd;
|
||||
int id, size;
|
||||
static pthread_mutex_t _async_init_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
_mutex_lock(&_async_init_mutex);
|
||||
if (!_async_ev) {
|
||||
int chid;
|
||||
|
||||
if ((_async_ev = malloc(sizeof(*_async_ev))) == NULL) {
|
||||
_mutex_unlock(&_async_init_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((chid = ChannelCreate(0)) == -1)
|
||||
{
|
||||
free(_async_ev);
|
||||
_async_ev = NULL;
|
||||
_mutex_unlock(&_async_init_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((_async_ev->sigev_coid = ConnectAttach(0, 0, chid, _NTO_SIDE_CHANNEL, 0)) == -1)
|
||||
{
|
||||
ChannelDestroy(chid);
|
||||
free(_async_ev);
|
||||
_async_ev = NULL;
|
||||
_mutex_unlock(&_async_init_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
_async_ev->sigev_notify = SIGEV_PULSE;
|
||||
_async_ev->sigev_priority = SIGEV_PULSE_PRIO_INHERIT;
|
||||
|
||||
if ((errno = pthread_create(&_async_ev_tid, NULL, _async_event_thread, (void *)chid)) != EOK)
|
||||
{
|
||||
ConnectDetach(_async_ev->sigev_coid);
|
||||
ChannelDestroy(chid);
|
||||
free(_async_ev);
|
||||
_async_ev = NULL;
|
||||
_mutex_unlock(&_async_init_mutex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
_mutex_unlock(&_async_init_mutex);
|
||||
|
||||
size = sizeof(*acc) + sizeof(struct _asyncmsg_put_header) * attr->max_num_buffer;
|
||||
acc = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_PHYS, NOFD, 0);
|
||||
if (acc == (struct _asyncmsg_connect_context *)MAP_FAILED) {
|
||||
return -1;
|
||||
}
|
||||
memset(acc, 0, sizeof(*acc));
|
||||
acd = &acc->acd;
|
||||
|
||||
flags |= _NTO_COF_NOSHARE;
|
||||
acd->attr = *attr;
|
||||
acd->flags = flags;
|
||||
acd->sendq_size = attr->max_num_buffer;
|
||||
acd->sendq = (struct _asyncmsg_put_header *)((char *)acc + sizeof(*acc));
|
||||
|
||||
if ((id = ConnectAttachExt(nd, pid, chid, index, flags, acd)) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
acd->sendq_head = acd->sendq_tail = acd->sendq_free = 0;
|
||||
acd->ev = *_async_ev;
|
||||
acd->ev.sigev_value.sival_int = id;
|
||||
acd->ev.sigev_code = 'T';
|
||||
if ((acd->ttimer = TimerCreate(CLOCK_REALTIME, &acd->ev)) == (timer_t)-1) {
|
||||
asyncmsg_connect_detach(id);
|
||||
return -1;
|
||||
}
|
||||
acc->flags = _ASYNCMSG_CONNECT_TIMEROFF;
|
||||
|
||||
acd->ev.sigev_code = 'P';
|
||||
if ((errno = pthread_mutex_init(&acd->mu, 0)) != EOK)
|
||||
{
|
||||
asyncmsg_connect_detach(id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((errno = pthread_cond_init(&acd->block_con, 0)) != EOK)
|
||||
{
|
||||
asyncmsg_connect_detach(id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_asyncmsg_handle(id, _ASYNCMSG_HANDLE_ADD, acc) == NULL) {
|
||||
asyncmsg_connect_detach(id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
__SRCVERSION("asyncmsg_connect_attach.c $Rev: 153052 $");
|
||||
48
lib/asyncmsg/asyncmsg_connect_attr.c
Normal file
48
lib/asyncmsg/asyncmsg_connect_attr.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "asyncmsg_priv.h"
|
||||
|
||||
int asyncmsg_connect_attr(int coid, struct _asyncmsg_connection_attr *old_attr, const struct _asyncmsg_connection_attr *new_attr)
|
||||
{
|
||||
struct _asyncmsg_connect_context *acc;
|
||||
struct _asyncmsg_connection_descriptor *acd;
|
||||
|
||||
if ((acc = _asyncmsg_handle(coid, _ASYNCMSG_HANDLE_LOOKUP, 0)) == NULL)
|
||||
return -1;
|
||||
acd = &acc->acd;
|
||||
|
||||
_mutex_lock(&acd->mu);
|
||||
if (old_attr) {
|
||||
*old_attr = acd->attr;
|
||||
}
|
||||
|
||||
if (new_attr) {
|
||||
acd->attr = *new_attr;
|
||||
/* I can't change max_buffer_size/buff_size, these
|
||||
* will causing acd->start changed, which means, the
|
||||
* memory kernel is referencing will gone :-(
|
||||
*/
|
||||
}
|
||||
_mutex_unlock(&acd->mu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__SRCVERSION("asyncmsg_connect_attr.c $Rev: 153052 $");
|
||||
79
lib/asyncmsg/asyncmsg_connect_detach.c
Normal file
79
lib/asyncmsg/asyncmsg_connect_detach.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include "asyncmsg_priv.h"
|
||||
|
||||
int asyncmsg_connect_detach(int coid)
|
||||
{
|
||||
struct _asyncmsg_connect_context *acc;
|
||||
struct _asyncmsg_connection_descriptor *acd;
|
||||
struct _asyncmsg_put_header *aph;
|
||||
|
||||
if (ConnectDetach(coid) == -1)
|
||||
return -1;
|
||||
|
||||
if ((acc = _asyncmsg_handle(coid, _ASYNCMSG_HANDLE_DELETE, 0)) == NULL)
|
||||
return -1;
|
||||
|
||||
timer_delete(acc->acd.ttimer);
|
||||
|
||||
/* if there is still message in the queue, remove them. The q is like:
|
||||
*
|
||||
* (free slot we know) --- (kernel point here) --- (lib point here)
|
||||
* free head tail
|
||||
*
|
||||
* free to head are already processed by kernel,
|
||||
* head to tail are messages already aysncmsg_put() but not processed,
|
||||
* tail to free are free slot for further asyncmsg_put().
|
||||
*/
|
||||
acd = &acc->acd;
|
||||
_mutex_lock(&acd->mu);
|
||||
while (acd->sendq_free != acd->sendq_tail) {
|
||||
aph = &acd->sendq[acd->sendq_free];
|
||||
/* cast to int to protect wrap over */
|
||||
if ((int)(acd->sendq_free - acd->sendq_head) >= 0) {
|
||||
aph->err = EBADF;
|
||||
}
|
||||
if (aph->cb) {
|
||||
aph->cb(aph->err, aph->iov, aph->handle);
|
||||
} else if (acd->attr.call_back) {
|
||||
acd->attr.call_back(aph->err, aph->iov, aph->handle);
|
||||
}
|
||||
|
||||
if (++acd->sendq_free >= acd->sendq_size)
|
||||
acd->sendq_free = 0;
|
||||
}
|
||||
|
||||
/* Sigh! have to use broadcast cause the condvar both
|
||||
* use for queue full, and asyncmsg_flush()
|
||||
*/
|
||||
pthread_cond_broadcast(&acd->block_con);
|
||||
_mutex_unlock(&acd->mu);
|
||||
pthread_cond_destroy(&acc->acd.block_con);
|
||||
pthread_mutex_destroy(&acc->acd.mu);
|
||||
munmap(acc, sizeof(*acc));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__SRCVERSION("asyncmsg_connect_detach.c $Rev: 153052 $");
|
||||
46
lib/asyncmsg/asyncmsg_flush.c
Normal file
46
lib/asyncmsg/asyncmsg_flush.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "asyncmsg_priv.h"
|
||||
|
||||
int asyncmsg_flush(int coid, int mode)
|
||||
{
|
||||
struct _asyncmsg_connect_context *acc;
|
||||
struct _asyncmsg_connection_descriptor *acd;
|
||||
int ret;
|
||||
|
||||
ret = MsgSendAsync(coid);
|
||||
if (ret == -1 || mode == ASYNCMSG_FLUSH_NONBLOCK)
|
||||
return ret;
|
||||
|
||||
if ((acc = _asyncmsg_handle(coid, _ASYNCMSG_HANDLE_LOOKUP, 0)) == NULL)
|
||||
return -1;
|
||||
|
||||
acd = &acc->acd;
|
||||
_mutex_lock(&acd->mu);
|
||||
while (acd->num_curmsg) {
|
||||
pthread_cond_wait(&acd->block_con, &acd->mu);
|
||||
}
|
||||
_mutex_unlock(&acd->mu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__SRCVERSION("asyncmsg_flush.c $Rev: 153052 $");
|
||||
30
lib/asyncmsg/asyncmsg_free.c
Normal file
30
lib/asyncmsg/asyncmsg_free.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/asyncmsg.h>
|
||||
|
||||
void asyncmsg_free(void *buf)
|
||||
{
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
__SRCVERSION("asyncmsg_free.c $Rev: 153052 $");
|
||||
116
lib/asyncmsg/asyncmsg_get.c
Normal file
116
lib/asyncmsg/asyncmsg_get.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include "asyncmsg_priv.h"
|
||||
|
||||
struct _asyncmsg_get_header* asyncmsg_get(int chid)
|
||||
{
|
||||
struct _asyncmsg_get_header *agh;
|
||||
struct _asyncmsg_channel_context *acc;
|
||||
iov_t *iov;
|
||||
size_t entsize;
|
||||
int n, used;
|
||||
|
||||
if ((acc = _asyncmsg_handle(chid, _ASYNCMSG_HANDLE_LOOKUP | _ASYNCMSG_HANDLE_CHANNEL, 0)) == NULL)
|
||||
return NULL;
|
||||
|
||||
entsize = sizeof(struct _asyncmsg_get_header) + sizeof(iov_t) + acc->buffer_size;
|
||||
|
||||
_mutex_lock(&acc->mutex);
|
||||
while (acc->num_free < acc->max_num_buffer) {
|
||||
void *bufs[1];
|
||||
|
||||
if (!acc->recvbuf_cb) {
|
||||
if ((agh = asyncmsg_malloc(entsize)) == NULL) {
|
||||
break;
|
||||
}
|
||||
memset(agh, 0, entsize);
|
||||
agh->iov = (iov_t *)(agh + 1);
|
||||
agh->iov->iov_base = agh->iov + 1;
|
||||
agh->iov->iov_len = acc->buffer_size;
|
||||
agh->parts = 1;
|
||||
agh->next = acc->free;
|
||||
acc->free = agh;
|
||||
acc->num_free++;
|
||||
} else {
|
||||
if (acc->recvbuf_cb(entsize, 1, (void **)bufs, ASYNCMSG_RECVBUF_ALLOC) <= 0) {
|
||||
break;
|
||||
}
|
||||
agh = bufs[0];
|
||||
memset(agh, 0, entsize);
|
||||
agh->iov = (iov_t *)(agh + 1);
|
||||
agh->iov->iov_base = agh->iov + 1;
|
||||
agh->iov->iov_len = acc->buffer_size;
|
||||
agh->parts = 1;
|
||||
agh->next = acc->free;
|
||||
acc->free = agh;
|
||||
acc->num_free++;
|
||||
}
|
||||
}
|
||||
|
||||
iov = acc->iovs;
|
||||
for (n = 0, agh = acc->free; n < acc->max_num_buffer && agh; n++, agh = agh->next)
|
||||
{
|
||||
SETIOV(&iov[n], agh, entsize);
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
_mutex_unlock(&acc->mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (agh) {
|
||||
acc->free = agh;
|
||||
agh = iov[n - 1].iov_base;
|
||||
agh->next = NULL;
|
||||
} else {
|
||||
acc->free = NULL;
|
||||
}
|
||||
acc->num_free -= n;
|
||||
_mutex_unlock(&acc->mutex);
|
||||
|
||||
if ((used = MsgReceiveAsync(chid, iov, n)) <= 0) {
|
||||
_mutex_lock(&acc->mutex);
|
||||
agh = iov[n - 1].iov_base;
|
||||
agh->next = acc->free;
|
||||
acc->free = iov[0].iov_base;
|
||||
acc->num_free += n;
|
||||
_mutex_unlock(&acc->mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (used < n) {
|
||||
_mutex_lock(&acc->mutex);
|
||||
agh = iov[n - 1].iov_base;
|
||||
agh->next = acc->free;
|
||||
acc->free = iov[used].iov_base;
|
||||
|
||||
agh = iov[used - 1].iov_base;
|
||||
agh->next = NULL;
|
||||
|
||||
acc->num_free += n - used;
|
||||
_mutex_unlock(&acc->mutex);
|
||||
}
|
||||
agh = iov[0].iov_base;
|
||||
return agh;
|
||||
}
|
||||
|
||||
__SRCVERSION("asyncmsg_get.c $Rev: 157149 $");
|
||||
29
lib/asyncmsg/asyncmsg_malloc.c
Normal file
29
lib/asyncmsg/asyncmsg_malloc.c
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/asyncmsg.h>
|
||||
|
||||
void *asyncmsg_malloc(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
__SRCVERSION("asyncmsg_malloc.c $Rev: 153052 $");
|
||||
59
lib/asyncmsg/asyncmsg_priv.h
Normal file
59
lib/asyncmsg/asyncmsg_priv.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef _ASYNCMSG_PRIV_H_INCLUDED
|
||||
#define _ASYNCMSG_PRIV_H_INCLUDED
|
||||
|
||||
#ifndef _ASYNCMSG_H_INCLUDED
|
||||
#include <sys/asyncmsg.h>
|
||||
#endif
|
||||
|
||||
#ifndef _STRING_H_INCLUDE
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
struct _asyncmsg_channel_context {
|
||||
pthread_mutex_t mutex;
|
||||
int (*recvbuf_cb)(size_t bufsize, unsigned num_bufs, void*bufs[], int flags);
|
||||
int buffer_size;
|
||||
int max_num_buffer;
|
||||
struct _asyncmsg_get_header *free;
|
||||
int num_free;
|
||||
iov_t *iovs;
|
||||
};
|
||||
|
||||
struct _asyncmsg_connect_context {
|
||||
unsigned flags;
|
||||
struct _asyncmsg_connection_descriptor acd;
|
||||
};
|
||||
#define _ASYNCMSG_CONNECT_TIMEROFF 1
|
||||
|
||||
/* by default, every get will try to receive 5 message */
|
||||
#define _ASYNCMSG_DEFAULT_GET 5
|
||||
|
||||
/* for _asyncmsg_handle */
|
||||
#define _ASYNCMSG_HANDLE_ADD 0
|
||||
#define _ASYNCMSG_HANDLE_LOOKUP 1
|
||||
#define _ASYNCMSG_HANDLE_DELETE 2
|
||||
#define _ASYNCMSG_HANDLE_CHANNEL 0x80000000
|
||||
|
||||
extern void * _asyncmsg_handle(int id, int cmd, void *handle);
|
||||
|
||||
#endif
|
||||
92
lib/asyncmsg/asyncmsg_put.c
Normal file
92
lib/asyncmsg/asyncmsg_put.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#include "asyncmsg_priv.h"
|
||||
|
||||
static int _asyncmsg_put_trigger(int coid, struct _asyncmsg_connect_context *acc)
|
||||
{
|
||||
/* figure out if we need to trigger kernel */
|
||||
acc->acd.num_curmsg++;
|
||||
if (acc->acd.attr.trigger_num_msg && acc->acd.num_curmsg >= acc->acd.attr.trigger_num_msg)
|
||||
{
|
||||
return MsgSendAsync(coid);
|
||||
}
|
||||
|
||||
/* if this is the first message, trigger & tick the ttimer */
|
||||
if (acc->flags & _ASYNCMSG_CONNECT_TIMEROFF) {
|
||||
TimerSettime(acc->acd.ttimer, 0, &acc->acd.attr.trigger_time, NULL);
|
||||
acc->flags &= ~_ASYNCMSG_CONNECT_TIMEROFF;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int asyncmsg_putv(int coid, const iov_t* iov, int parts, unsigned handle, int (*call_back)(int err, void* buf, unsigned handle))
|
||||
{
|
||||
struct _asyncmsg_connect_context *acc;
|
||||
struct _asyncmsg_connection_descriptor *acd;
|
||||
struct _asyncmsg_put_header *aph;
|
||||
unsigned new_tail;
|
||||
int err;
|
||||
|
||||
if ((acc = _asyncmsg_handle(coid, _ASYNCMSG_HANDLE_LOOKUP, 0)) == NULL)
|
||||
return -1;
|
||||
acd = &acc->acd;
|
||||
|
||||
_mutex_lock(&acd->mu);
|
||||
for (;;) {
|
||||
new_tail = acd->sendq_tail + 1;
|
||||
if (new_tail >= acd->sendq_size)
|
||||
new_tail = 0;
|
||||
|
||||
if (new_tail != acd->sendq_free)
|
||||
break;
|
||||
|
||||
/* put list is full */
|
||||
if (acd->flags & _NTO_COF_NONBLOCK) {
|
||||
_mutex_unlock(&acd->mu);
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
pthread_cond_wait(&acd->block_con, &acd->mu);
|
||||
}
|
||||
|
||||
aph = &acd->sendq[acd->sendq_tail];
|
||||
acd->sendq_tail = new_tail;
|
||||
|
||||
aph->err = 0;
|
||||
aph->iov = (iov_t *)iov;
|
||||
aph->parts = parts;
|
||||
aph->handle = handle;
|
||||
aph->cb = call_back;
|
||||
|
||||
err = _asyncmsg_put_trigger(coid, acc);
|
||||
_mutex_unlock(&acd->mu);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int asyncmsg_put(int coid, const void *buff, size_t size, unsigned handle, int (*call_back)(int err, void* buf, unsigned handle))
|
||||
{
|
||||
return asyncmsg_putv(coid, (iov_t *)buff, (int)-size, handle, call_back);
|
||||
}
|
||||
|
||||
|
||||
__SRCVERSION("asyncmsg_put.c $Rev: 153052 $");
|
||||
23
lib/asyncmsg/common.mk
Normal file
23
lib/asyncmsg/common.mk
Normal file
@@ -0,0 +1,23 @@
|
||||
#
|
||||
# Copyright 2004, QNX Software Systems Ltd. All Rights Reserved.
|
||||
#
|
||||
# This source code may contain confidential information of QNX Software
|
||||
# Systems Ltd. (QSSL) and its licensors. Any use, reproduction,
|
||||
# modification, disclosure, distribution or transfer of this software,
|
||||
# or any software which includes or is based upon any of this code, is
|
||||
# prohibited unless expressly authorized by QSSL by written agreement. For
|
||||
# more information (including whether this source code file has been
|
||||
# published) please email licensing@qnx.com.
|
||||
#
|
||||
ifndef QCONFIG
|
||||
QCONFIG=qconfig.mk
|
||||
endif
|
||||
include $(QCONFIG)
|
||||
|
||||
define PINFO
|
||||
PINFO DESCRIPTION = Asynchronous Message Passing Library
|
||||
endef
|
||||
INSTALLDIR=usr/lib
|
||||
NAME=asyncmsg
|
||||
USEFILE=
|
||||
include $(MKFILES_ROOT)/qtargets.mk
|
||||
8
lib/asyncmsg/mips/Makefile
Normal file
8
lib/asyncmsg/mips/Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
LIST=VARIANT
|
||||
ifndef QRECURSE
|
||||
QRECURSE=recurse.mk
|
||||
ifdef QCONFIG
|
||||
QRDIR=$(dir $(QCONFIG))
|
||||
endif
|
||||
endif
|
||||
include $(QRDIR)$(QRECURSE)
|
||||
1
lib/asyncmsg/mips/a.be/Makefile
Normal file
1
lib/asyncmsg/mips/a.be/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
include ../../common.mk
|
||||
1
lib/asyncmsg/mips/a.le/Makefile
Normal file
1
lib/asyncmsg/mips/a.le/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
include ../../common.mk
|
||||
1
lib/asyncmsg/mips/so.be/Makefile
Normal file
1
lib/asyncmsg/mips/so.be/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
include ../../common.mk
|
||||
1
lib/asyncmsg/mips/so.le/Makefile
Normal file
1
lib/asyncmsg/mips/so.le/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
include ../../common.mk
|
||||
45
lib/asyncmsg/module.tmpl
Normal file
45
lib/asyncmsg/module.tmpl
Normal file
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0"?>
|
||||
<module name="asyncmsg">
|
||||
|
||||
<type>Element</type>
|
||||
|
||||
<classification>SDK</classification>
|
||||
|
||||
<supports>
|
||||
<availability ref="ostargets"/>
|
||||
</supports>
|
||||
|
||||
<source available="false">
|
||||
<location type="">.</location>
|
||||
</source>
|
||||
|
||||
<GroupOwner>os</GroupOwner>
|
||||
|
||||
<contents>
|
||||
<component id="SharedObj" generated="true">
|
||||
<kind type="library"/>
|
||||
<location basedir="{cpu}/so{.:endian}" runtime="true">
|
||||
libasyncmsg.so
|
||||
</location>
|
||||
</component>
|
||||
<component id="SharedArchive" generated="true">
|
||||
<kind type="library"/>
|
||||
<location runtime="false" basedir="{cpu}/so{.:endian}">
|
||||
libasyncmsgS.a
|
||||
</location>
|
||||
</component>
|
||||
|
||||
<component id="Archive" generated="true">
|
||||
<kind type="library"/>
|
||||
<location basedir="{cpu}/a{.:endian}" runtime="false">
|
||||
libasyncmsg.a
|
||||
</location>
|
||||
</component>
|
||||
|
||||
</contents>
|
||||
|
||||
<!-- Dependencies -->
|
||||
<requires>
|
||||
<part build="false" location="services/system"/>
|
||||
</requires>
|
||||
</module>
|
||||
8
lib/asyncmsg/ppc/Makefile
Normal file
8
lib/asyncmsg/ppc/Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
LIST=VARIANT
|
||||
ifndef QRECURSE
|
||||
QRECURSE=recurse.mk
|
||||
ifdef QCONFIG
|
||||
QRDIR=$(dir $(QCONFIG))
|
||||
endif
|
||||
endif
|
||||
include $(QRDIR)$(QRECURSE)
|
||||
1
lib/asyncmsg/ppc/a.be/Makefile
Normal file
1
lib/asyncmsg/ppc/a.be/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
include ../../common.mk
|
||||
1
lib/asyncmsg/ppc/so.be/Makefile
Normal file
1
lib/asyncmsg/ppc/so.be/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
include ../../common.mk
|
||||
8
lib/asyncmsg/sh/Makefile
Normal file
8
lib/asyncmsg/sh/Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
LIST=VARIANTS
|
||||
ifndef QRECURSE
|
||||
QRECURSE=recurse.mk
|
||||
ifdef QCONFIG
|
||||
QRDIR=$(dir $(QCONFIG))
|
||||
endif
|
||||
endif
|
||||
include $(QRDIR)$(QRECURSE)
|
||||
1
lib/asyncmsg/sh/a.le/Makefile
Normal file
1
lib/asyncmsg/sh/a.le/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
include ../../common.mk
|
||||
1
lib/asyncmsg/sh/so.le/Makefile
Normal file
1
lib/asyncmsg/sh/so.le/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
include ../../common.mk
|
||||
8
lib/asyncmsg/unit_test/Makefile
Normal file
8
lib/asyncmsg/unit_test/Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
LIST=CPU
|
||||
ifndef QRECURSE
|
||||
QRECURSE=recurse.mk
|
||||
ifdef QCONFIG
|
||||
QRDIR=$(dir $(QCONFIG))
|
||||
endif
|
||||
endif
|
||||
include $(QRDIR)$(QRECURSE)
|
||||
127
lib/asyncmsg/unit_test/block_get.c
Normal file
127
lib/asyncmsg/unit_test/block_get.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <process.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/asyncmsg.h>
|
||||
|
||||
char *msg = "AsyncMsg Passing";
|
||||
int chid = -1, coid;
|
||||
int getisready = 0;
|
||||
|
||||
void *get_thread(void *arg)
|
||||
{
|
||||
struct _asyncmsg_get_header *agh, *agh1;
|
||||
|
||||
/* async channel */
|
||||
if ((chid = asyncmsg_channel_create(_NTO_CHF_SENDER_LEN, 0666, 2048, 5, NULL, NULL)) == -1) {
|
||||
perror("channel_create");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((agh = asyncmsg_get(chid)) == NULL) {
|
||||
perror("get");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printf("Got message(s): \n\n");
|
||||
while (agh1 = agh) {
|
||||
agh = agh1->next;
|
||||
printf("from process: %d (%d)\n", agh1->info.pid, getpid());
|
||||
printf("msglen: %d (%d)\n", agh1->info.msglen, strlen(msg) + 1);
|
||||
printf("srclen: %d\n", agh1->info.srcmsglen);
|
||||
printf("err: %d\n", agh1->err);
|
||||
printf("parts: %d\n", agh1->parts);
|
||||
printf("msg: %s\n\n", (char *)agh1->iov->iov_base);
|
||||
asyncmsg_free(agh1);
|
||||
}
|
||||
|
||||
if (asyncmsg_channel_destroy(chid) == -1) {
|
||||
perror("channel_detach");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The asyncmsg_get() will be blocked, and let's see if a put
|
||||
* could wake it up
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct _asyncmsg_connection_attr aca;
|
||||
int pid = 0;
|
||||
|
||||
if (argc > 1) {
|
||||
if ((pid = fork()) == -1) {
|
||||
perror("fork");
|
||||
return -1;
|
||||
}
|
||||
if (!pid) {
|
||||
get_thread(0);
|
||||
return 0;
|
||||
} else {
|
||||
/* we lied, the parent don't know the chid in client,
|
||||
* we assume it's 1 :)
|
||||
*/
|
||||
chid = 1;
|
||||
}
|
||||
} else {
|
||||
if ((errno = pthread_create(0, 0, get_thread, NULL)) != EOK) {
|
||||
perror("pthread_create");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Let the get thread block */
|
||||
sleep(1);
|
||||
|
||||
if (chid == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&aca, 0, sizeof(aca));
|
||||
aca.buffer_size = 2048;
|
||||
aca.max_num_buffer = 5;
|
||||
aca.trigger_num_msg = 1;
|
||||
|
||||
if ((coid = asyncmsg_connect_attach(0, pid, chid, 0, 0, &aca)) == -1) {
|
||||
perror("connect_attach");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((asyncmsg_put(coid, msg, strlen(msg) + 1, 0, 0)) == -1) {
|
||||
perror("put");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
|
||||
if (asyncmsg_connect_detach(coid) == -1) {
|
||||
perror("connect_detach");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__SRCVERSION("block_get.c $Rev: 153052 $");
|
||||
98
lib/asyncmsg/unit_test/bulk_put.c
Normal file
98
lib/asyncmsg/unit_test/bulk_put.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <process.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/asyncmsg.h>
|
||||
|
||||
int callback(int err, void *cmsg, unsigned handle)
|
||||
{
|
||||
printf("Callback: err = %d, msg = %p, handle = %d\n",
|
||||
err, cmsg, handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiple put, then see if get could got all of them.
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
int chid, coid, i;
|
||||
struct _asyncmsg_connection_attr aca;
|
||||
struct _asyncmsg_get_header *agh, *agh1;
|
||||
char msg[3][80];
|
||||
|
||||
if ((chid = asyncmsg_channel_create(_NTO_CHF_SENDER_LEN, 0666, 2048, 5, NULL, NULL)) == -1) {
|
||||
perror("channel_create");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&aca, 0, sizeof(aca));
|
||||
aca.buffer_size = 2048;
|
||||
aca.max_num_buffer = 5;
|
||||
aca.trigger_num_msg = 3;
|
||||
|
||||
if ((coid = asyncmsg_connect_attach(0, 0, chid, 0, 0, &aca)) == -1) {
|
||||
perror("connect_attach");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
sprintf(msg[i], "Async Message Passing (msgid %d)\n", i);
|
||||
if ((asyncmsg_put(coid, msg[i], strlen(msg[i]) + 1, 1234, callback)) == -1) {
|
||||
perror("put");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((agh = asyncmsg_get(chid)) == NULL) {
|
||||
perror("get");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Got message(s): \n\n");
|
||||
while (agh1 = agh) {
|
||||
agh = agh1->next;
|
||||
printf("from process: %d (%d)\n", agh1->info.pid, getpid());
|
||||
printf("msglen: %d (%d)\n", agh1->info.msglen, strlen(msg) + 1);
|
||||
printf("srclen: %d\n", agh1->info.srcmsglen);
|
||||
printf("err: %d\n", agh1->err);
|
||||
printf("parts: %d\n", agh1->parts);
|
||||
printf("msg: %s\n\n", (char *)agh1->iov->iov_base);
|
||||
asyncmsg_free(agh1);
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
|
||||
if (asyncmsg_connect_detach(coid) == -1) {
|
||||
perror("connect_detach");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (asyncmsg_channel_destroy(chid) == -1) {
|
||||
perror("channel_detach");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__SRCVERSION("bulk_put.c $Rev: 153052 $");
|
||||
20
lib/asyncmsg/unit_test/common.mk
Normal file
20
lib/asyncmsg/unit_test/common.mk
Normal file
@@ -0,0 +1,20 @@
|
||||
ifndef QCONFIG
|
||||
QCONFIG=qconfig.mk
|
||||
endif
|
||||
include $(QCONFIG)
|
||||
|
||||
USEFILE=
|
||||
|
||||
TESTS = $(basename $(notdir $(SRCS)))
|
||||
INSTALLDIR=/dev/null
|
||||
ICLEAN=$(TESTS)
|
||||
ALL_DEPENDENCIES=$(TESTS)
|
||||
|
||||
LIBS += asyncmsg
|
||||
|
||||
EXTRA_LIBVPATH=$(PROJECT_ROOT)/../$(CPU)/a.be
|
||||
|
||||
include $(MKFILES_ROOT)/qtargets.mk
|
||||
|
||||
$(TESTS): %: %.o
|
||||
$(TARGET_BUILD)
|
||||
146
lib/asyncmsg/unit_test/flush_put.c
Normal file
146
lib/asyncmsg/unit_test/flush_put.c
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <process.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/asyncmsg.h>
|
||||
|
||||
int num_callback_run = 0;
|
||||
int chid;
|
||||
|
||||
int callback(int err, void *cmsg, unsigned handle)
|
||||
{
|
||||
num_callback_run++;
|
||||
printf("Callback: err = %d, msg = %p, handle = %d\n",
|
||||
err, cmsg, handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void * thread_for_get(void *arg)
|
||||
{
|
||||
int pchid = (int)arg;
|
||||
struct _pulse pulse;
|
||||
struct _asyncmsg_get_header *agh, *agh1;
|
||||
|
||||
/* waiting for the event */
|
||||
if (MsgReceivePulse(pchid, &pulse, sizeof(pulse), NULL) == -1) {
|
||||
perror("MsgReceivePulse");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((agh = asyncmsg_get(chid)) == NULL) {
|
||||
perror("get");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printf("Got message(s): \n\n");
|
||||
while (agh1 = agh) {
|
||||
agh = agh1->next;
|
||||
printf("from process: %d (%d)\n", agh1->info.pid, getpid());
|
||||
printf("msglen: %d\n", agh1->info.msglen);
|
||||
printf("srclen: %d\n", agh1->info.srcmsglen);
|
||||
printf("err: %d\n", agh1->err);
|
||||
printf("parts: %d\n", agh1->parts);
|
||||
printf("msg: %s\n\n", (char *)agh1->iov->iov_base);
|
||||
asyncmsg_free(agh1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* No trigger for put, but we force an flush(), see if all
|
||||
* messages could be pushed out.
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
int coid, pchid, i;
|
||||
struct sigevent gev;
|
||||
struct _asyncmsg_connection_attr aca;
|
||||
char msg[4][80];
|
||||
|
||||
/* prepare the event */
|
||||
if ((pchid = ChannelCreate(0)) == -1) {
|
||||
perror("ChannelCreate");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((errno = pthread_create(0, 0, thread_for_get, (void *)pchid)) != EOK)
|
||||
{
|
||||
perror("pthread_create");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((gev.sigev_coid = ConnectAttach(0, 0, pchid, _NTO_SIDE_CHANNEL, 0)) == -1)
|
||||
{
|
||||
perror("ConnectAttach");
|
||||
return -1;
|
||||
}
|
||||
gev.sigev_notify = SIGEV_PULSE;
|
||||
gev.sigev_priority = SIGEV_PULSE_PRIO_INHERIT;
|
||||
|
||||
/* async channel */
|
||||
if ((chid = asyncmsg_channel_create(_NTO_CHF_SENDER_LEN, 0666, 2048, 5, &gev, NULL)) == -1) {
|
||||
perror("channel_create");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&aca, 0, sizeof(aca));
|
||||
aca.buffer_size = 2048;
|
||||
aca.max_num_buffer = 5;
|
||||
aca.trigger_num_msg = 0;
|
||||
aca.call_back = callback;
|
||||
|
||||
if ((coid = asyncmsg_connect_attach(0, 0, chid, 0, 0, &aca)) == -1) {
|
||||
perror("connect_attach");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* put up 4 messages */
|
||||
for (i = 0; i < 2; i++) {
|
||||
sprintf(msg[i], "Async Message Passing (msgid %d)\n", i);
|
||||
if ((asyncmsg_put(coid, msg[i], strlen(msg[i]) + 1, 1234, callback)) == -1) {
|
||||
perror("put");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
asyncmsg_flush(coid, 0);
|
||||
|
||||
/* give the put callback a chance to run */
|
||||
while (num_callback_run < 2)
|
||||
delay(500);
|
||||
|
||||
if (asyncmsg_connect_detach(coid) == -1) {
|
||||
perror("connect_detach");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (asyncmsg_channel_destroy(chid) == -1) {
|
||||
perror("channel_detach");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__SRCVERSION("flush_put.c $Rev: 153052 $");
|
||||
123
lib/asyncmsg/unit_test/pulse_get.c
Normal file
123
lib/asyncmsg/unit_test/pulse_get.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <process.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/asyncmsg.h>
|
||||
|
||||
char *msg = "AsyncMsg Passing";
|
||||
|
||||
int callback(int err, void *cmsg, unsigned handle)
|
||||
{
|
||||
printf("Callback: err = %d, msg = %p (%p), handle = %d\n",
|
||||
err, cmsg, msg, handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple test. Create a channel, connect to it, put a message,
|
||||
* get them, done
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
int chid, coid, pchid;
|
||||
struct sigevent gev;
|
||||
struct _pulse pulse;
|
||||
struct _asyncmsg_connection_attr aca;
|
||||
struct _asyncmsg_get_header *agh, *agh1;
|
||||
|
||||
/* prepare the event */
|
||||
if ((pchid = ChannelCreate(0)) == -1) {
|
||||
perror("ChannelCreate");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((gev.sigev_coid = ConnectAttach(0, 0, pchid, _NTO_SIDE_CHANNEL, 0)) == -1)
|
||||
{
|
||||
perror("ConnectAttach");
|
||||
return -1;
|
||||
}
|
||||
gev.sigev_notify = SIGEV_PULSE;
|
||||
gev.sigev_priority = SIGEV_PULSE_PRIO_INHERIT;
|
||||
|
||||
/* async channel */
|
||||
if ((chid = asyncmsg_channel_create(0, 0666, 2048, 5, &gev, NULL)) == -1) {
|
||||
perror("channel_create");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&aca, 0, sizeof(aca));
|
||||
aca.buffer_size = 2048;
|
||||
aca.max_num_buffer = 5;
|
||||
aca.trigger_num_msg = 1;
|
||||
aca.call_back = callback;
|
||||
|
||||
if ((coid = asyncmsg_connect_attach(0, 0, chid, 0, 0, &aca)) == -1) {
|
||||
perror("connect_attach");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if ((asyncmsg_put(coid, msg, strlen(msg) + 1, 0, 0)) == -1) {
|
||||
perror("put");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* waiting for the event */
|
||||
if (MsgReceivePulse(pchid, &pulse, sizeof(pulse), NULL) == -1) {
|
||||
perror("MsgReceivePulse");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((agh = asyncmsg_get(chid)) == NULL) {
|
||||
perror("get");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Got message(s): \n\n");
|
||||
while (agh1 = agh) {
|
||||
agh = agh1->next;
|
||||
printf("from process: %d (%d)\n", agh1->info.pid, getpid());
|
||||
printf("msglen: %d (%d)\n", agh1->info.msglen, strlen(msg) + 1);
|
||||
printf("srclen: %d\n", agh1->info.srcmsglen);
|
||||
printf("err: %d\n", agh1->err);
|
||||
printf("parts: %d\n", agh1->parts);
|
||||
printf("msg: %s\n\n", (char *)agh1->iov->iov_base);
|
||||
asyncmsg_free(agh1);
|
||||
}
|
||||
|
||||
/* give the callback a chance to run */
|
||||
sleep(1);
|
||||
|
||||
if (asyncmsg_connect_detach(coid) == -1) {
|
||||
perror("connect_detach");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (asyncmsg_channel_destroy(chid) == -1) {
|
||||
perror("channel_detach");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__SRCVERSION("pulse_get.c $Rev: 153052 $");
|
||||
98
lib/asyncmsg/unit_test/put_and_get.c
Normal file
98
lib/asyncmsg/unit_test/put_and_get.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <process.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/asyncmsg.h>
|
||||
|
||||
char *msg = "AsyncMsg Passing";
|
||||
|
||||
int callback(int err, void *cmsg, unsigned handle)
|
||||
{
|
||||
printf("Callback: err = %d, msg = %p (%p), handle = %d\n",
|
||||
err, cmsg, msg, handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple test. Create a channel, connect to it, put a message,
|
||||
* get them, done
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
int chid, coid;
|
||||
struct _asyncmsg_connection_attr aca;
|
||||
struct _asyncmsg_get_header *agh, *agh1;
|
||||
|
||||
if ((chid = asyncmsg_channel_create(0, 0666, 2048, 5, NULL, NULL)) == -1) {
|
||||
perror("channel_create");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&aca, 0, sizeof(aca));
|
||||
aca.buffer_size = 2048;
|
||||
aca.max_num_buffer = 5;
|
||||
aca.trigger_num_msg = 1;
|
||||
|
||||
if ((coid = asyncmsg_connect_attach(0, 0, chid, 0, 0, &aca)) == -1) {
|
||||
perror("connect_attach");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if ((asyncmsg_put(coid, msg, strlen(msg) + 1, 1234, callback)) == -1) {
|
||||
perror("put");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((agh = asyncmsg_get(chid)) == NULL) {
|
||||
perror("get");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Got message(s): \n\n");
|
||||
while (agh1 = agh) {
|
||||
agh = agh1->next;
|
||||
printf("from process: %d (%d)\n", agh1->info.pid, getpid());
|
||||
printf("msglen: %d (%d)\n", agh1->info.msglen, strlen(msg) + 1);
|
||||
printf("srclen: %d\n", agh1->info.srcmsglen);
|
||||
printf("err: %d\n", agh1->err);
|
||||
printf("parts: %d\n", agh1->parts);
|
||||
printf("msg: %s\n\n", (char *)agh1->iov->iov_base);
|
||||
asyncmsg_free(agh1);
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
|
||||
if (asyncmsg_connect_detach(coid) == -1) {
|
||||
perror("connect_detach");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (asyncmsg_channel_destroy(chid) == -1) {
|
||||
perror("channel_detach");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__SRCVERSION("put_and_get.c $Rev: 153052 $");
|
||||
127
lib/asyncmsg/unit_test/timer_put.c
Normal file
127
lib/asyncmsg/unit_test/timer_put.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* $QNXLicenseC:
|
||||
* Copyright 2007, QNX Software Systems. All Rights Reserved.
|
||||
*
|
||||
* You must obtain a written license from and pay applicable license fees to QNX
|
||||
* Software Systems before you may reproduce, modify or distribute this software,
|
||||
* or any work that includes all or part of this software. Free development
|
||||
* licenses are available for evaluation and non-commercial purposes. For more
|
||||
* information visit http://licensing.qnx.com or email licensing@qnx.com.
|
||||
*
|
||||
* This file may contain contributions from others. Please review this entire
|
||||
* file for other proprietary rights or license notices, as well as the QNX
|
||||
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
|
||||
* for other information.
|
||||
* $
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <process.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/asyncmsg.h>
|
||||
|
||||
int callback(int err, void *cmsg, unsigned handle)
|
||||
{
|
||||
printf("Callback: err = %d, msg = %p, handle = %d\n",
|
||||
err, cmsg, handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the get trigger to 2 seconds, put up 4 messages, see we could get a
|
||||
* notification for get after 2 seconds.
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
int chid, coid, pchid, i;
|
||||
struct sigevent gev;
|
||||
struct _pulse pulse;
|
||||
struct _asyncmsg_connection_attr aca;
|
||||
struct _asyncmsg_get_header *agh, *agh1;
|
||||
char msg[4][80];
|
||||
|
||||
/* prepare the event */
|
||||
if ((pchid = ChannelCreate(0)) == -1) {
|
||||
perror("ChannelCreate");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((gev.sigev_coid = ConnectAttach(0, 0, pchid, _NTO_SIDE_CHANNEL, 0)) == -1)
|
||||
{
|
||||
perror("ConnectAttach");
|
||||
return -1;
|
||||
}
|
||||
gev.sigev_notify = SIGEV_PULSE;
|
||||
gev.sigev_priority = SIGEV_PULSE_PRIO_INHERIT;
|
||||
|
||||
/* async channel */
|
||||
if ((chid = asyncmsg_channel_create(_NTO_CHF_SENDER_LEN, 0666, 2048, 5, &gev, NULL)) == -1) {
|
||||
perror("channel_create");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&aca, 0, sizeof(aca));
|
||||
aca.buffer_size = 2048;
|
||||
aca.max_num_buffer = 5;
|
||||
aca.trigger_num_msg = 0;
|
||||
aca.trigger_time.nsec = 2000000000L;
|
||||
aca.trigger_time.interval_nsec = 0;
|
||||
aca.call_back = callback;
|
||||
|
||||
if ((coid = asyncmsg_connect_attach(0, 0, chid, 0, 0, &aca)) == -1) {
|
||||
perror("connect_attach");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* put up 4 messages */
|
||||
for (i = 0; i < 4; i++) {
|
||||
sprintf(msg[i], "Async Message Passing (msgid %d)\n", i);
|
||||
if ((asyncmsg_put(coid, msg[i], strlen(msg[i]) + 1, 1234, callback)) == -1) {
|
||||
perror("put");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* waiting for the event */
|
||||
if (MsgReceivePulse(pchid, &pulse, sizeof(pulse), NULL) == -1) {
|
||||
perror("MsgReceivePulse");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((agh = asyncmsg_get(chid)) == NULL) {
|
||||
perror("get");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Got message(s): \n\n");
|
||||
while (agh1 = agh) {
|
||||
agh = agh1->next;
|
||||
printf("from process: %d (%d)\n", agh1->info.pid, getpid());
|
||||
printf("msglen: %d (%d)\n", agh1->info.msglen, strlen(msg) + 1);
|
||||
printf("srclen: %d\n", agh1->info.srcmsglen);
|
||||
printf("err: %d\n", agh1->err);
|
||||
printf("parts: %d\n", agh1->parts);
|
||||
printf("msg: %s\n\n", (char *)agh1->iov->iov_base);
|
||||
asyncmsg_free(agh1);
|
||||
}
|
||||
|
||||
/* give the callback a chance to run */
|
||||
sleep(1);
|
||||
|
||||
if (asyncmsg_connect_detach(coid) == -1) {
|
||||
perror("connect_detach");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (asyncmsg_channel_destroy(chid) == -1) {
|
||||
perror("channel_detach");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__SRCVERSION("timer_put.c $Rev: 153052 $");
|
||||
8
lib/asyncmsg/unit_test/x86/Makefile
Normal file
8
lib/asyncmsg/unit_test/x86/Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
LIST=VARIANT
|
||||
ifndef QRECURSE
|
||||
QRECURSE=recurse.mk
|
||||
ifdef QCONFIG
|
||||
QRDIR=$(dir $(QCONFIG))
|
||||
endif
|
||||
endif
|
||||
include $(QRDIR)$(QRECURSE)
|
||||
1
lib/asyncmsg/unit_test/x86/o/Makefile
Normal file
1
lib/asyncmsg/unit_test/x86/o/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
include ../../common.mk
|
||||
8
lib/asyncmsg/x86/Makefile
Normal file
8
lib/asyncmsg/x86/Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
LIST=VARIANT
|
||||
ifndef QRECURSE
|
||||
QRECURSE=recurse.mk
|
||||
ifdef QCONFIG
|
||||
QRDIR=$(dir $(QCONFIG))
|
||||
endif
|
||||
endif
|
||||
include $(QRDIR)$(QRECURSE)
|
||||
1
lib/asyncmsg/x86/a.shared/Makefile
Normal file
1
lib/asyncmsg/x86/a.shared/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
include ../../common.mk
|
||||
1
lib/asyncmsg/x86/a/Makefile
Normal file
1
lib/asyncmsg/x86/a/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
include ../../common.mk
|
||||
1
lib/asyncmsg/x86/so/Makefile
Normal file
1
lib/asyncmsg/x86/so/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
include ../../common.mk
|
||||
Reference in New Issue
Block a user