Hi,
The following is sample code in QNX 6 Programmer’s Guide.
The QNX IPC mechanism is unaccustomed to me, so I am confused.
My question is
-
When ‘message_handler’ function is called ? And can I invoke the function
on my purpose by signal(?) or anything ? or the function can be invoked by
only system(ex. Process Manager) ? -
What is pulse ?
event.sigev_code = pulse_attach(dpp,
MSG_FLAG_ALLOC_PULSE, 0,
&timer_tick, NULL)
in here, what does ‘pulse’ mean ? interrupt ? time tick ?
Thanks in advance,
Hoon
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#define THREAD_POOL_PARAM_T dispatch_context_t
#include <sys/iofunc.h>
#include <sys/dispatch.h>
static resmgr_connect_funcs_t connect_func;
static resmgr_io_funcs_t io_func;
static iofunc_attr_t attr;
int
timer_tick(message_context_t *ctp, int code,
unsigned flags, void *handle) {
union sigval value = ctp->msg->pulse.value;
/* Do some useful work on every timer firing… */
printf(“received timer event, value %d\n”, value.sival_int);
return 0;
}
int
message_handler(message_context_t *ctp, int code,
unsigned flags, void *handle ) {
printf(“received private message, type %d\n”, code);
return 0;
}
int
main(int argc, char **argv) {
thread_pool_attr_t pool_attr;
thread_pool_t *tpp;
dispatch_t *dpp;
resmgr_attr_t resmgr_attr;
int id;
int timer_id;
struct sigevent event;
struct _itimer itime;
if((dpp = dispatch_create()) == NULL) {
fprintf(stderr,
“%s: Unable to allocate dispatch handle.\n”,
argv[0]);
return EXIT_FAILURE;
}
memset(&pool_attr, 0, sizeof pool_attr);
pool_attr.handle = dpp;
/* We are doing resmgr and pulse-type attaches */
pool_attr.context_alloc = dispatch_context_alloc;
pool_attr.block_func = dispatch_block;
pool_attr.handler_func = dispatch_handler;
pool_attr.context_free = dispatch_context_free;
pool_attr.lo_water = 2;
pool_attr.hi_water = 4;
pool_attr.increment = 1;
pool_attr.maximum = 50;
if((tpp = thread_pool_create(&pool_attr,
POOL_FLAG_EXIT_SELF)) == NULL) {
fprintf(stderr,
“%s: Unable to initialize thread pool.\n”,
argv[0]);
return EXIT_FAILURE;
}
iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_func,
_RESMGR_IO_NFUNCS, &io_func);
iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);
memset(&resmgr_attr, 0, sizeof resmgr_attr);
resmgr_attr.nparts_max = 1;
resmgr_attr.msg_max_size = 2048;
if((id = resmgr_attach(dpp, &resmgr_attr, “/dev/mynull”,
_FTYPE_ANY, 0,
&connect_func, &io_func, &attr)) == -1) {
fprintf(stderr, “%s: Unable to attach name.\n”, argv[0]);
return EXIT_FAILURE;
}
/*
We want to handle our own private messages, of type
0x5000 to 0x5fff
*/
if(message_attach(dpp, NULL, 0x5000, 0x5fff,
&message_handler, NULL) == -1) {
fprintf(stderr,
“Unable to attach to private message range.\n”);
return EXIT_FAILURE;
}
/* Initialize an event structure, and attach a pulse to it */
if((event.sigev_code = pulse_attach(dpp,
MSG_FLAG_ALLOC_PULSE, 0,
&timer_tick, NULL)) == -1) {
fprintf(stderr, “Unable to attach timer pulse.\n”);
return EXIT_FAILURE;
}
/* Connect to our channel */
if((event.sigev_coid = message_connect(dpp,
MSG_FLAG_SIDE_CHANNEL)) == -1) {
fprintf(stderr, “Unable to attach to channel.\n”);
return EXIT_FAILURE;
}
event.sigev_notify = SIGEV_PULSE;
event.sigev_priority = -1;
/*
We could create several timers and use different
sigev values for each
*/
event.sigev_value.sival_int = 0;
if((timer_id = TimerCreate(CLOCK_REALTIME, &event)) == -1) {;
fprintf(stderr,
“Unable to attach channel and connection.\n”);
return EXIT_FAILURE;
}
/* And now setup our timer to fire every second */
itime.nsec = 1000000000;
itime.interval_nsec = 1000000000;
TimerSettime(timer_id, 0, &itime, NULL);
/* Never returns */
thread_pool_start(tpp);
return EXIT_SUCCESS;
}