I’m having conceptual problems (apparently) and actual problems
(really). I’m not able to receive the pulse sent by MsgDeliverEvent()
in the “client” below. Conceptually, server does rcvid=MsgReceive(),
client does MsgSend(), server calls MsgDeliverEvent(rcvid, …) which
supposedly sends a pulse to the client which hasn’t even created a
channel yet. Where does the pulse go, then? In order for the client
to actually receive the pulse, a channel has to be given in the
MsgReceive(). I tried just using “1”, guessing that a channel might
have been automagically created by doing a MsgSend (doesn’t make much
sense but…) No go… MsgReceive() fails with “invalid process”.
When i call ChannelCreate() (which returns 2) and use that in the
MsgReceive(), it just blocks, although the MsgDeliverEvent() completed
without error. Apparently that’s not the right channel.
I run the above test by running the server first, then running the
client with the process id and channel id of the server passed in on
the command line. This way at least the first Send/Receive/Reply all
work. But if i run the client with no args, using the connection id
obtained from name_open(), the MsgSend fails with ENOSYS, which isn’t
even listed as an error for MsgSend.
This is all very unexpectedly puzzling.
// “Server”
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/dispatch.h>
main( int argc, char *argv[] )
{
int retstat;
name_attach_t *na;
char buf[512];
struct _msg_info info;
if ( argc > 1 )
retstat = atoi( argv[1] );
na = name_attach( 0, “craig”, 0 );
if ( na )
{
printf(“process id: %d\n”, getpid());
printf(“channel id: %d\n”, na->chid);
// printf(“mount id: %d\n”, na->mntid); // always seems to be 0
}
else
printf(“name_attach fail: %s (%d)\n”, strerror(errno), errno);
while ( 1 )
{
int rcvid = MsgReceive( na->chid, buf, sizeof(buf), &info );
if ( rcvid > 0 )
{
printf(“rcvd: `%s’ (rcvid: %d)\n”, buf, rcvid);
printf(“pid: %d\n”, info.pid);
printf(“tid: %d\n”, info.tid);
printf(“chid: %d\n”, info.chid);
printf(“scoid: %d\n”, info.scoid);
printf(“coid: %d\n”, info.coid);
printf(“msglen: %d\n”, info.msglen);
strcpy( buf, “I think i know” );
printf(“reply with: %s (status: %d)\n”, buf, retstat);
if ( MsgReply( rcvid, retstat, buf, strlen(buf)+1 ) == -1 )
fprintf(stderr, “MsgReply fail: %s (%d)\n”, strerror(errno), errno);
}
else if ( rcvid == 0 )
{
printf(“received pulse\n”);
}
else
fprintf(stderr, “MsgReceive fail: %s (%d)\n”, strerror(errno), errno);
if ( rcvid > 0 )
{
struct sigevent event;
event.sigev_coid = rcvid;
event.sigev_code = 13;
event.sigev_value.sival_int = 0x06660666;
printf(“Calling MsgDeliverEvent(%d, …)\n”, rcvid);
if ( MsgDeliverEvent(rcvid, &event) == -1 )
fprintf(stderr, “MsgDeliverEvent fail: %s (%d)\n”, strerror(errno), errno);
}
}
return 0;
}
// “Client”
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/dispatch.h>
int main( int argc, char *argv[] )
{
int coid;
char resp[512];
if ( argc == 1 )
{
int coid = name_open( “craig”, 0 );
if ( coid > 0 )
printf(“connection id: %d\n”, coid);
else
printf(“name_open fail: %s (%d)\n”, strerror(errno), errno);
}
else if ( argc > 2 )
{
int pid = atoi(argv[1]);
int chid = atoi(argv[2]);
printf(“attaching to pid %d, chid %d\n”, pid, chid);
coid = ConnectAttach( 0, pid, chid, _NTO_SIDE_CHANNEL, 0 );
if ( coid > 0 )
printf(“connection id: %d\n”, coid);
else
printf(“ConnectAttach fail: %s (%d)\n”, strerror(errno), errno);
}
else
printf(“Need args\n”);
char *msg = “Whose woods these are”;
int status = MsgSend( coid, msg, strlen(msg)+1, resp, sizeof(resp) );
if ( status == -1 )
fprintf(stderr, “MsgSend fail: %s (%d)\n”, strerror(errno), errno);
else
printf(“resp: %s (status: %d)\n”, resp, status);
int chid = ChannelCreate(0);
printf(“Created channel %d\n”, chid);
char buf[512];
struct _msg_info info;
int rcvid = MsgReceive( chid, buf, sizeof(buf), &info );
if ( rcvid > 0 )
printf(“Received msg\n”);
else if ( rcvid == 0 )
{
printf(“Received pulse\n”);
struct _pulse *pp = (_pulse *)buf;
printf(“code\n”, pp->code);
printf(“data\n”, pp->value.sival_int);
printf(“scoid\n”, pp->scoid);
}
else
fprintf(stderr, “MsgReceive fail: %s (%d)\n”, strerror(errno), errno);
if ( argc == 1 )
name_close(coid);
ConnectDetach(coid);
printf(“exiting…\n”);
return 0;
}