Hi all,
back in october I reported a prob with Trigger() (with libmig4nto) causing a SEGV exception
in the application w/o a stack trace.
(Message-ID:<39F795C2.4C09357E@hentschel.net>)
No solution was found back then, but Sean Boudreau supplied me with the following
code snipped which would work under NTO. After some time off on another project,
I finally tried implementing the suggestion in our app. Here his suggestion first :
#include <sys/neutrino.h>
#include <sys/socket.h>
#include <sys/iomgr.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <errno.h>
#define CODE 0 //whatever
#define VALUE 0 //whatever
int
main(void)
{
int sfd;
struct sockaddr_in in;
struct sigevent event;
int coid, chid, note, rcvid;
struct _pulse pulse;
struct _msg_info info;
unsigned char buf[100];
if((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
perror(“socket”);
return 1;
}
memset(&in, 0x00, sizeof in);
in.sin_len = sizeof in;
in.sin_family = AF_INET;
in.sin_addr.s_addr = INADDR_ANY;
in.sin_port = htons(200);
if(bind(sfd, (struct sockaddr *)&in, sizeof in) == -1)
{
perror(“bind”);
return 1;
}
fcntl(sfd, F_SETFL, fcntl(sfd, F_GETFL) | O_NONBLOCK);
if((chid = ChannelCreate(0)) == -1)
{
perror(“ChannelCreate”);
return -1;
}
if((coid = ConnectAttach(0, 0, chid, _NTO_SIDE_CHANNEL, 0)) == -1)
{
perror(“ConnectAttach”);
return 1;
}
event.sigev_notify = SIGEV_PULSE;
event.sigev_coid = coid;
event.sigev_priority = getprio(0);
event.sigev_code = CODE;
event.sigev_value.sival_int = VALUE;
for(;
{
if((note = ionotify(sfd, _NOTIFY_ACTION_POLLARM, _NOTIFY_COND_INPUT, &event)) == -1)
{
perror(“ionotify”);
return 1;
}
if(!(note & _NOTIFY_COND_INPUT))
{
for(;
{
if((rcvid = MsgReceive(chid, &pulse, sizeof pulse, &info)) == -1)
{
perror(“MsgReceive”);
return 1;
}
if(pulse.type != _PULSE_TYPE || pulse.subtype != _PULSE_SUBTYPE)
{
MsgError(rcvid, ENOSYS);
continue;
}
if(pulse.code != CODE || pulse.value.sival_int != VALUE)
{
continue;
}
break;
}
}
for(;
{
/* Process data */
memset(buf, 0x00, sizeof buf);
if(read(sfd, buf, sizeof buf) == -1)
{
break;
}
buf[sizeof buf -1] = ‘\0’;
printf("%s\n", buf);
}
if(errno != EWOULDBLOCK)
{
perror(“read”);
return -1;
}
}
}
Now, the problem is I still need the migration library. This means I
have to block using Receive(). Since the migration lib
blocks pulses, I “fixed” it up to forward pulses to my app :
$ diff /usr/src/qssl/nto/mig4nto.org/mig4nto/ipc_funcs.c ipc_funcs.c
512c512,513
< continue; /* got an unexpected pulse, nothing to do */
return process_msg(rcvid, &rec_msg, (iov_t ) msgmx, parts);
// (TH) continue; / got an unexpected pulse, nothing to do */
With that I should be able to get the Pulses to my app and distingiush
them by looking for 0 as return from Receive(). Below is the code which
gets called if Receive() would return 0, also “arm_sockets()” get’s
called every time a new socket is created.
Now, what I of course neglected to mention to Sean was that I had to
listen on multiple sockets. Therefore my actual implementation looks like :
#ifdef QNXNTO
static void NTOPulseHandler(void *msg)
{
struct _pulse pulse;
pulse = * (struct _pulse *) msg;
if (pulse.type == !_PULSE_TYPE || pulse.subtype != _PULSE_SUBTYPE)
{
printf(“not a PULSE – help!!! \n”);
arm_sockets();
return;
}
do
{
switch (pulse.code)
{
case PULSECODE :
switch (pulse.value.sival_int)
{
case PULSEVALUE_IO :
printf(“Got PULSE \n”);
SocketEventHandler();
break;
default :
printf(“unknown PULSE VAL \n”);
break;
}
default :
printf(“unknown PULSE CODE \n”);
break;
}
}
while (arm_sockets() == NTO_SCKT_INPUT);
}
extern magic_t magic;
static int arm_sockets(void)
{
int note ;
static int coid = 0;
struct sigevent event;
SOCKET_TYPE *sockNode;
/*
- make sure we got something
*/
if (socketRoot == NULL)
{
printf("%s: arm_sockets: no Socket Root ! \n", localKBName);
return NTO_SCKT_ERROR;
}
/*
- setup our event structure on which we get notified with
/
if (!coid)
if ((coid = ConnectAttach(0,0,magic.ipc_chid, _NTO_SIDE_CHANNEL, 0)) == -1)
{
printf("%s: arm_sockets: ConnectAttach ! \n", localKBName);
coid = 0;
return NTO_SCKT_ERROR;
}
event.sigev_notify = SIGEV_PULSE; / nomen est omen */
event.sigev_coid = coid;
event.sigev_priority = getprio(0);
event.sigev_code = PULSECODE;
event.sigev_value.sival_int = PULSEVALUE_IO;
sockNode = socketRoot;
while (sockNode)
{
if (note = ionotify(sockNode->socket, _NOTIFY_ACTION_POLLARM, _NOTIFY_COND_INPUT, &event) == -1)
{
MyLogMsg(errLev, “%s: Error arming sockets : Errno %d ‘%s’\n”, localKBName, errno, sys_errlist[errno]);
return NTO_SCKT_ERROR;
}
if (note & _NOTIFY_COND_INPUT)
return NTO_SCKT_INPUT;
sockNode = NextSocketEntry(sockNode);
}
:
return NTO_SCKT_NOINPUT;
}
#endif
The sockets get initialized and bound somewhere else in the app, and I don’t wan’t
to paste the whole cruft here. Suffice to say that it keeps a linked list
which starts at socketRoot and returns NULL if the last socket has been
reached.
Now, rather unexpectedly, MsgReceive() in libmig4nto exits the app and
stderr prints “I/O possible” when talking to any of the ports bound to sockets in
question.
Why would this cause MsgReceive() exit an application (no SIGSEGV) ?
Any thoughts on what might be wrong ?
Thanks
-Th