mq_notify woes

I’m having trouble getting pulse notification using mq_notify to work with
Photon app under QNX 6.2.1B. I’ve appended a very simple receiver and
sender below. The sender seems to work (I can see the message count
incrementing on the file), but the receiver never notices the new messages.
This taken almost exactly from the example in the “Interprocess
Communication” chapter of the Photon guide. Any help will be appreciated.

-msgrecv.c------------------------------------------------------------------

/* AppBuilder Photon Code Lib /
/
Version 2.01 */

/* Standard headers */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <mqueue.h>
#include <fcntl.h>

/* Local headers */
#include “ablibs.h”
#include “abimport.h”
#include “proto.h”

/* Application Options string /
const char ApOptions[] =
AB_OPTIONS “”; /
Add your options in the “” */

mqd_t Queue = -1;
struct sigevent Signal;

static int MessageHandler( void *data, int rcvid,
void *message, size_t mbsize )
{
ssize_t sz;
unsigned prio;
char buf[ 10 ];

while( (sz = mq_receive( Queue, buf, sizeof( buf ), &prio )) >= 0 )
{
printf( “recvd: %s\n”, buf );
}
mq_notify( Queue, &Signal );

return( Pt_CONTINUE );
}

int
Init( int argc, char *argv[] )
{
int pulse;

/* eliminate ‘unreferenced’ warnings */
argc = argc, argv = argv;


pulse = PtAppCreatePulse( NULL, -1 );
PtAppAddInput( NULL, pulse, MessageHandler, NULL );
PtPulseArm( NULL, pulse, &Signal );

Queue = mq_open( “my_queue”, O_RDONLY | O_CREAT | O_NONBLOCK,
S_IRUSR | S_IWUSR, NULL );

mq_notify( Queue, &Signal );

return( Pt_CONTINUE );
}

-msgsend.c-----------------------------------------------

#include <unistd.h>
#include <fcntl.h>

int main( void )
{
int fd;

char buf[ 10 ] = “Print Me”;

fd = open( “my_queue”, O_WRONLY );
if ( fd != -1 )
write( fd, buf, sizeof( buf ) );

return 0;
}

Robert Palmbos <rpalmbos.please@no.harscotrack.spam.com.thanks> wrote:

static int MessageHandler( void *data, int rcvid,
void *message, size_t mbsize )
{
ssize_t sz;
unsigned prio;
char buf[ 10 ];

while( (sz = mq_receive( Queue, buf, sizeof( buf ), &prio )) >= 0 )
{
printf( “recvd: %s\n”, buf );
}
mq_notify( Queue, &Signal );

This is broken. You must call mq_notify() then drain the queue.

Otherwise, you have a race condition – if an element is sent to the
queue after your mq_receive(), but before your call to mq_notify()
you will never be notified.

return( Pt_CONTINUE );
}

int
Init( int argc, char *argv[] )
{
int pulse;

/* eliminate ‘unreferenced’ warnings */
argc = argc, argv = argv;



pulse = PtAppCreatePulse( NULL, -1 );
PtAppAddInput( NULL, pulse, MessageHandler, NULL );
PtPulseArm( NULL, pulse, &Signal );

Queue = mq_open( “my_queue”, O_RDONLY | O_CREAT | O_NONBLOCK,
S_IRUSR | S_IWUSR, NULL );

mq_notify( Queue, &Signal );

Same here… if there is an element in the queue when you call
mq_notify(), then you will never be notified. It only notifies
when the queue goes from empty to non-empty. (Unless you
absolutely know that nothing could be on the queue at this
point. If testing, and the queue is still around…)

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

“David Gibbs” <dagibbs@qnx.com> wrote in message
news:bi0q85$dh8$1@nntp.qnx.com

Robert Palmbos <> rpalmbos.please@no.harscotrack.spam.com.thanks> > wrote:

static int MessageHandler( void *data, int rcvid,
void *message, size_t mbsize )
{
ssize_t sz;
unsigned prio;
char buf[ 10 ];

while( (sz = mq_receive( Queue, buf, sizeof( buf ), &prio )) >= 0 )
{
printf( “recvd: %s\n”, buf );
}
mq_notify( Queue, &Signal );

This is broken. You must call mq_notify() then drain the queue.

Otherwise, you have a race condition – if an element is sent to the
queue after your mq_receive(), but before your call to mq_notify()
you will never be notified.

My original QNX4 (and its QNX6 port) program uses mq_notify() as you
describe, ie before doing the receive and it empties the queue at startup.
I’ve never had any problems under QNX4, but the QNX6 version is never
notified. Neither my application nor this simple test work regardless of
where the mq_notify() is placed.

Well, the example worked after I passed an mq_attr structure with mq_msglen
set to mq_open( ). My application also passes the msglen so I’m not sure
yet what causes my application not to work.

“Robert Palmbos” <rpalmbos.please@no.harscotrack.spam.com.thanks> wrote in
message news:bi2ecn$1pk$1@inn.qnx.com

“David Gibbs” <> dagibbs@qnx.com> > wrote in message
news:bi0q85$dh8$> 1@nntp.qnx.com> …
Robert Palmbos <> rpalmbos.please@no.harscotrack.spam.com.thanks> > wrote:

static int MessageHandler( void *data, int rcvid,
void *message, size_t mbsize )
{
ssize_t sz;
unsigned prio;
char buf[ 10 ];

while( (sz = mq_receive( Queue, buf, sizeof( buf ), &prio )) >= 0 )
{
printf( “recvd: %s\n”, buf );
}
mq_notify( Queue, &Signal );

This is broken. You must call mq_notify() then drain the queue.

Otherwise, you have a race condition – if an element is sent to the
queue after your mq_receive(), but before your call to mq_notify()
you will never be notified.

My original QNX4 (and its QNX6 port) program uses mq_notify() as you
describe, ie before doing the receive and it empties the queue at startup.
I’ve never had any problems under QNX4, but the QNX6 version is never
notified. Neither my application nor this simple test work regardless of
where the mq_notify() is placed.
\