Msg* function problem

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.

Manoj Panicker <manojmpanicker@worldnet.att.net> wrote:

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.

Remember that pulses can only send a fixed size message, and no more. They are
non-blocking messages that have a 32bit value and an 8bit code in the msg.
You cannot overload them to send more data.

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.

The server received the message correctly as you used MsgSend(), and did not
“pulse” it to the server.

Perhaps I’m not completely understanding what you’re trying to do, but if
you’re trying to send more then a 32bit value+8bit code in a pulse it
won’t work.

-Adam
amallory@qnx.com

Manoj Panicker <manojmpanicker@worldnet.att.net> wrote:

Hello,



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.

Whenever you receive a pulse – whether with MsgReceive() or MsgReceivePulse,
you will receive a pulse message of type struct _pulse. You will not
receive a struct sigevent. struct sigevent is used to describe the
event you want delivered (signal/pulse), but when it is received, it
will be received as a signal (interrupting flow, going to handler, or
whatever) or as a pulse (as if sent with MsgSendPulse(), giving you a
struct _pulse).

-David

QNX Training Services
dagibbs@qnx.com