_select_receive

In my ongoing effort to port our QNX4 software to QNX6, I have created
a _select_receive workalike using the method suggested by Xiaodan on
comp.os.qnx on 2002-08-12 02:36:35 PST. Basically, the principle
seems simple and straightforward. The problem I am having is that the
value of the value member of the pulse that I receive (my substituted
pulse in place of the signal used by the lib select) does not appear
to contain what select_event is looking for. Using the select_block.c
as an example, it appears that the value received from the iomanager
should simply be passed through unaltered. This is what I do, however,
when my version of select returns (with the correct return value) the
file descriptor set does not have the appropriate element set.

What am I doing wrong here ?

Here is my code that replaces select, and _select_receive

-------- select replacement
int Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *tvptr)
{
struct sigevent event;
struct timespec ts;
int policy;
struct sched_param params;

if(tvptr) {
if(tvptr->tv_sec < 0 ||tvptr->tv_usec < 0) {
return errno= EINVAL, -1;
}

ts.tv_sec= tvptr->tv_sec ;
ts.tv_nsec= tvptr->tv_usec * 1000L ;
}

pthread_getschedparam(pthread_self(), &policy, &params);
SIGEV_PULSE_INIT(&event, m_coidMain, params.sched_priority, m_pulseidSelect, 0);

return _select_event(nfds, readfds, writefds, exceptfds, tvptr ? &ts : 0,
&event, _select_receive, 0);
}


-------- select_receive replacement
int SelectReceive(const struct timespec *ts, union sigval *value, void arg)
{
struct sigevent event;
uint64_t to=(uint64_t)(ts->tv_sec
1000000000)+(uint64_t)(ts->tv_nsec);
int rcvid;
msg_header_t msg;

SIGEV_UNBLOCK_INIT(&event);

while(1) {
TimerTimeout(CLOCK_MONOTONIC, _NTO_TIMEOUT_RECEIVE, &event, &to, NULL);
rcvid=MsgReceive(m_chidMain, &msg, sizeof msg, NULL);
if(rcvid == -1) {
return -1; // implement timeout
} else if(rcvid == 0) {
if(msg.code == m_pulseidSelect) {
*value=msg.value; // value does not appear to be suitable for select_event
printf(“SelectReceive(): msg.value = %02x”, msg.value);
return 0;
} else {
// handle our messages
}
}
}

return -1;
}

Further information.

The source of the problem is that the tcpip stack (large QNX6.2)
does not set _NOTIFY_COND_INPUT when it notifies select for an
incoming connection (i.e. notification to do an accept). I have
verified this by including the source to event_select in my code
and debugging. The event_select function correctly sets
_NOTIFY_COND_INPUT in the flags when it messages to io-net, but
when the pulse is received from io-net signalling an incoming
connection it’s value member contains the correct fd (and serial)
but does not have the _NOTIFY_COND_INPUT flag set. This means
that the select_event code does not add the fd into the set.

Why is the tcpip stack not setting _NOTIFY_COND_INPUT for an
incoming connection ?

Rennie

Rennie Allen <rallen@csical.com> wrote:

In my ongoing effort to port our QNX4 software to QNX6, I have created
a _select_receive workalike using the method suggested by Xiaodan on
comp.os.qnx on 2002-08-12 02:36:35 PST. Basically, the principle
seems simple and straightforward. The problem I am having is that the
value of the value member of the pulse that I receive (my substituted
pulse in place of the signal used by the lib select) does not appear
to contain what select_event is looking for. Using the select_block.c
as an example, it appears that the value received from the iomanager
should simply be passed through unaltered. This is what I do, however,
when my version of select returns (with the correct return value) the
file descriptor set does not have the appropriate element set.

What am I doing wrong here ?

Here is my code that replaces select, and _select_receive

-------- select replacement
int Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *tvptr)
{
struct sigevent event;
struct timespec ts;
int policy;
struct sched_param params;

if(tvptr) {
if(tvptr->tv_sec < 0 ||tvptr->tv_usec < 0) {
return errno= EINVAL, -1;
}

ts.tv_sec= tvptr->tv_sec ;
ts.tv_nsec= tvptr->tv_usec * 1000L ;
}

pthread_getschedparam(pthread_self(), &policy, &params);
SIGEV_PULSE_INIT(&event, m_coidMain, params.sched_priority, m_pulseidSelect, 0);

SIGEV_PULSE_INIT(&event, m_coidMain, params.sched_priority, SI_NOTIFY, 0);

See the docs for iofunc_notify_trigger().

-seanb

Sean Boudreau wrote:

Rennie Allen <> rallen@csical.com> > wrote:

See the docs for iofunc_notify_trigger().

Thank you.

Rennie