Hello,
Im new to QNX and am trying to understand how the message passing IPC works.
I started with an example given in the “MsgDeliverEvent” function
description of the library reference at the QNX support site.
http://qdn.qnx.com/support/docs/neutrino_2.11_en/lib_ref/m/msgdeliverevent.h
tml
The example shows how a event can be registered with a server and how the
server returns the event at a later time. The example made use of a pulse.
So the server would send a MsgDeliverEvent and the client would wait on a
MsgReceivePulse.
The given example works fine. Then I modified the code to use a sigevent
structure to be passed to the server instead of the my_msg structure. Then I
had the client wait on a MsgReceive function.
Now the description of MsgReceive says that it will wait for a
message/pulse. So the pulse sent by the server should be correctly received
by the client but that is not what happens. I print the contents of msg (of
type sigevent) and i see some difference in the value received. If I use
MsgReceivePulse (with a struct pulse as parameter) instead of MsgReceive,
with everything else remaining the same, the behavior is fine.
Both the programs are attached below for reference. The output from the
execution is also attached.
The Server Program
/* server.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/neutrino.h>
#include <sys/iomsg.h>
#include <sys/dispatch.h>
#include “myheader.h”
int main( int argc, char *argv)
{
int rcvid;
/ struct my_msg msg; */
struct sigevent msg;
name_attach_t *attach;
/* attach the name the client will use to find us /
/ our channel will be in the attach structure */
if ( (attach = name_attach( NULL, MY_SERV, 0 )) == NULL)
{
printf(“server:failed to attach name, errno %d\n”, errno );
exit(1);
}
/* wait for the message from the client /
rcvid = MsgReceive( attach->chid, &msg, sizeof( msg ), NULL );
/ if ( msg.type == MSG_GIVE_PULSE )
{
wait until it is time to notify the client */
sleep(4);
printf(“Server: The sigevent structure contains the following values\n
notify: %d \n signo : %d coid: %d \n prio: %d code :%d value :
%d\n”,msg.sigev_notify, msg.sigev_signo, msg.sigev_coid, msg.sigev_priority,
msg.sigev_code, msg.sigev_value);
/* deliver notification to client that client requested /
/ MsgDeliverEvent( rcvid, &msg.event );/
MsgDeliverEvent( rcvid, &msg);
printf(“server:delivered event\n”);
/ } else
{
printf(“server: unexpected message \n”);
}
*/
return 0;
}
The client Program
/* client.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/neutrino.h>
#include <sys/iomsg.h>
#include “myheader.h”
int main( int argc, char *argv)
{
int chid, coid, srv_coid, rcvid;
/ struct my_msg msg; */
struct _pulse pulse;
struct sigevent msg,rmsg;
/* we need a channel to receive the pulse notification on */
chid = ChannelCreate( 0 );
/* and we need a connection to that channel for the pulse to be
delivered on */
coid = ConnectAttach( 0, 0, chid, _NTO_SIDE_CHANNEL, 0 );
/* fill in the event structure for a pulse */
SIGEV_PULSE_INIT( &msg, coid, SIGEV_PULSE_PRIO_INHERIT,
MY_PULSE_CODE, 0 );
printf(“The sigevent structure contains the following values\n notify: %d
\n signo : %d coid: %d \n prio: %d code :%d value : %d\n”,msg.sigev_notify,
msg.sigev_signo, msg.sigev_coid, msg.sigev_priority, msg.sigev_code,
msg.sigev_value);
/* msg.type = MSG_GIVE_PULSE; */
/* find the server */
if ( (srv_coid = name_open( MY_SERV, 0 )) == -1)
{
printf(“failed to find server, errno %d\n”, errno );
exit(1);
}
/* give the pulse event we initialized above to the server for
later delivery */
MsgSend( srv_coid, &msg, sizeof(msg), NULL, 0 );
/* wait for the pulse from the server */
rcvid = MsgReceive( chid, &rmsg, sizeof(rmsg) , NULL );
printf(“Client: The sigevent structure contains the following values\n
notify: %d \n signo : %d coid: %d \n prio: %d code :%d value :
%d\n”,msg.sigev_notify, msg.sigev_signo, msg.sigev_coid, msg.sigev_priority,
msg.sigev_code, msg.sigev_value);
printf(“Client: The sigevent structure contains the following values\n
notify: %d \n signo : %d coid: %d \n prio: %d code :%d value
:%d\n”,rmsg.sigev_notify, rmsg.sigev_signo, rmsg.sigev_coid,
rmsg.sigev_priority, rmsg.sigev_code, rmsg.sigev_value);
return 0;
}
The output from the execution is shown below. The server is already
running.
./client
The sigevent structure contains the following values
<<<<NB: This message printed by client
notify: 4
signo : 1073741826 coid: 1073741826
prio: -1 code :5 value : 0
Server: The sigevent structure contains the following values
notify: 4
signo : 1073741826 coid: 1073741826
prio: -1 code :5 value : 0
server:delivered event
Client: The sigevent structure contains the following values <<NB: The
client again prints the msg structure sent to the server.
notify: 4
signo : 1073741826 coid: 1073741826
prio: -1 code :5 value : 0
Client: The sigevent structure contains the following values <<The client
prints the structure received from the server.
notify: 0
signo : -251 coid: -251
prio: 16384 code :3 value : 0
[1] + Done ./server
Note that the server receives the msg correctly, and sends it back w/o any
modifications on the structure. So something goofs up in the
MsgDeliverEvent.