message_attach & pulse_attach

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

  1. 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) ?

  2. 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;
}

A pulse is simply a pre-defined message (pre-defined in the QNX headers)
with has a fixed size:
From <sys/neutino.h>:
struct _pulse {
_Uint16t type;
_Uint16t subtype;
_Int8t code;
_Uint8t zero[3];
union sigval value;
_Int32t scoid;
};
The code member of the _pulse structure is simply an identifier for you to
use in your code to distinguish between different pulses your
process/threads receives. Pulses are typically used to notify your process
that an event has occurred while sticking with the QNX’s IPC architecture
(processes block using MsgReceive*()). I find most often in my code I use
pulses attached to timers in order to periodically wake my threads up to do
some work.

The pulse_attach() function is used with resource managers and simply tells
the QNX kernel that your resource manager’s dispatch interface will be
expecting pulses and that you want a particular function to handle those
pulses: If you call
pulse_attach( dpp, MSG_FLAG_ALLOC_PULSE, 123, PulseHandler,
pointerToAnyDataYouWant)
the dispatch_handler() function in the resource manager will invoke your
PulseHandler() function and pass it the pulse code that caused the
PulseHandler() to be invoked. If your want to handle several pulses in your
resource manager, you simply call pulse_attach() for each pulse code you
want PulseHandler() to handle (you can specify the same handler function and
simply decide what action to take in your PulseHandler() based on the ‘code’
argument passed to it).

The ‘handle’ argument passed to pulse_attach() can be anything you would
like it to be- the kernel simply passes this data directly to your
PulseHandler() function as the last argument. If you pass in a handle
argument, you have to know what it is in your PulseHandler() in order to get
any use out of it.

Your can call your PulseHandler() function at anytime (if you would like),
but it is not likely you would need to.

Keep in mind that when attaching messages, pulses or signals to a resource
manager’s dispatch interface, you are force to use the dispatch_*() methods
for blocking and handling I/O messages which are sent to your resource
manager.

Hope this helps



“Hoon Jung” <hjung@3ic.co.kr> wrote in message
news:9und74$b1p$1@inn.qnx.com

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

  1. 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) ?

  2. 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;
}

Your help quench my thirst, but not fully.
Okay, I understand what is pulse. However how can I generate pulse with
specific code ?
The pulse attached to timer is generated when timer is expired, but in this
case the pulse is generated by system. Can I generate a pulse with specific
code on my purpose ?

Thanks in advance,
Hoon

“Rover Fan” <RoverFan@Chartermi.net> wrote in message
news:9uomnv$a70$1@inn.qnx.com

A pulse is simply a pre-defined message (pre-defined in the QNX headers)
with has a fixed size:
From <sys/neutino.h>:
struct _pulse {
_Uint16t type;
_Uint16t subtype;
_Int8t code;
_Uint8t zero[3];
union sigval value;
_Int32t scoid;
};
The code member of the _pulse structure is simply an identifier for you to
use in your code to distinguish between different pulses your
process/threads receives. Pulses are typically used to notify your process
that an event has occurred while sticking with the QNX’s IPC architecture
(processes block using MsgReceive*()). I find most often in my code I use
pulses attached to timers in order to periodically wake my threads up to
do
some work.

The pulse_attach() function is used with resource managers and simply
tells
the QNX kernel that your resource manager’s dispatch interface will be
expecting pulses and that you want a particular function to handle those
pulses: If you call
pulse_attach( dpp, MSG_FLAG_ALLOC_PULSE, 123, PulseHandler,
pointerToAnyDataYouWant)
the dispatch_handler() function in the resource manager will invoke your
PulseHandler() function and pass it the pulse code that caused the
PulseHandler() to be invoked. If your want to handle several pulses in
your
resource manager, you simply call pulse_attach() for each pulse code you
want PulseHandler() to handle (you can specify the same handler function
and
simply decide what action to take in your PulseHandler() based on the
‘code’
argument passed to it).

The ‘handle’ argument passed to pulse_attach() can be anything you would
like it to be- the kernel simply passes this data directly to your
PulseHandler() function as the last argument. If you pass in a handle
argument, you have to know what it is in your PulseHandler() in order to
get
any use out of it.

Your can call your PulseHandler() function at anytime (if you would like),
but it is not likely you would need to.

Keep in mind that when attaching messages, pulses or signals to a resource
manager’s dispatch interface, you are force to use the dispatch_*()
methods
for blocking and handling I/O messages which are sent to your resource
manager.

Hope this helps

In article <9upb78$mbg$1@inn.qnx.com>,
“Hoon Jung” <hjung@3ic.co.kr> writes:

Your help quench my thirst, but not fully.
Okay, I understand what is pulse. However how can I generate pulse with
specific code ?
The pulse attached to timer is generated when timer is expired, but in this
case the pulse is generated by system. Can I generate a pulse with specific
code on my purpose ?

In QNX, channels are things you can receive messages on, and connection ids
are used to send messages. Create channels using ChannelCreate or the
dispatch/resource manager API and create connection ids using ConnectAttach,
variants of “open” or message_connect.

int chid = ChannelCreate(0);

int coid = ConnectAttach(
0, //network node - 0 is local
0, //Process id - 0 is this process
chid, //channel to attach to
_NTO_SIDE_CHANNEL, //to avoid interfering with file descriptors
0 //flags
);

int code = 10;
int priority = getprio();
int value = 2307575; //some value

MsgSendPulse(coid, priority, code, value);

struct _pulse p;
MsgReceivePulse(chid, &p, sizeof p, 0);

assert(p.sigval.sival_int == value);

Tom

Hoon Jung <hjung@3ic.co.kr> wrote:

Your help quench my thirst, but not fully.
Okay, I understand what is pulse. However how can I generate pulse with
specific code ?

The lowest call is MsgSendPulse().

The pulse attached to timer is generated when timer is expired, but in this
case the pulse is generated by system. Can I generate a pulse with specific
code on my purpose ?

In this case, the “pulse” is not “generated by system”. It is the application (you) prepared,
passed to system, and while certain event happened (in this case, timer expired),
the system “send back” the pules you specified.

You can of cause prepare a struct pulse, and MsgSendPulse() it.

-xtang


Thanks in advance,
Hoon

“Rover Fan” <> RoverFan@Chartermi.net> > wrote in message
news:9uomnv$a70$> 1@inn.qnx.com> …
A pulse is simply a pre-defined message (pre-defined in the QNX headers)
with has a fixed size:
From <sys/neutino.h>:
struct _pulse {
_Uint16t type;
_Uint16t subtype;
_Int8t code;
_Uint8t zero[3];
union sigval value;
_Int32t scoid;
};
The code member of the _pulse structure is simply an identifier for you to
use in your code to distinguish between different pulses your
process/threads receives. Pulses are typically used to notify your process
that an event has occurred while sticking with the QNX’s IPC architecture
(processes block using MsgReceive*()). I find most often in my code I use
pulses attached to timers in order to periodically wake my threads up to
do
some work.

The pulse_attach() function is used with resource managers and simply
tells
the QNX kernel that your resource manager’s dispatch interface will be
expecting pulses and that you want a particular function to handle those
pulses: If you call
pulse_attach( dpp, MSG_FLAG_ALLOC_PULSE, 123, PulseHandler,
pointerToAnyDataYouWant)
the dispatch_handler() function in the resource manager will invoke your
PulseHandler() function and pass it the pulse code that caused the
PulseHandler() to be invoked. If your want to handle several pulses in
your
resource manager, you simply call pulse_attach() for each pulse code you
want PulseHandler() to handle (you can specify the same handler function
and
simply decide what action to take in your PulseHandler() based on the
‘code’
argument passed to it).

The ‘handle’ argument passed to pulse_attach() can be anything you would
like it to be- the kernel simply passes this data directly to your
PulseHandler() function as the last argument. If you pass in a handle
argument, you have to know what it is in your PulseHandler() in order to
get
any use out of it.

Your can call your PulseHandler() function at anytime (if you would like),
but it is not likely you would need to.

Keep in mind that when attaching messages, pulses or signals to a resource
manager’s dispatch interface, you are force to use the dispatch_*()
methods
for blocking and handling I/O messages which are sent to your resource
manager.

Hope this helps