Please help with POSIX message queue (mq_notify)
Please help with my little sample program dealing with mq_notify, which is followed in the example of the book "Programming for the Real World - POSIX.4" by Bill Gallmeister.
The program creates 2 msg queues, to read and write. The read queue is setup to be notified when there is a new message. The request handler will read the message and respond appropriately with the size of data be read and send per mq_send call to the write queue.
When this program runs, it will hang at the line mq_notify(...) in the main function. My workstation will reset after that. Please help.
My workstation (uname -a): SunOS meandog 5.6 Generic_105181-16 sun4u sparc SUNW,Ultra-1
/***** sample program starts here *****/
#include <stdio.h>
#include <mqueue.h>
#include <sys/stat.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#define MESSAGE_SIZE 50000
unsigned char buffer[MESSAGE_SIZE];
char *rd_name = "/read_queue";
char *wr_name = "/write_queue";
mqd_t rd_q, wr_q;
int fd;
void request_handler(int sig_number, siginfo_t info, void ignored)
{
int size_to_read;
unsigned int prio;
struct sigevent se;
int retval;
int count;
/* Re-register for next notification */
se.sigev_notify = SIGEV_SIGNAL;
se.sigev_signo = SIGRTMIN;
se.sigev_value.sival_int = 0;
retval = mq_notify(rd_q, &se);
if (retval == -1)
{
printf("mq_notify errno = %i\n", errno);
exit(1);
}
/* Process the request */
mq_receive(rd_q, (void *)&size_to_read, sizeof(int), &prio);
while ((count = read(fd, &buffer, size_to_read)) > 0)
{
mq_send(wr_q, buffer, count, 0);
}
mq_send(wr_q, buffer, 0, 0); /* size of 0 to end the request */
return;
}
int main (int argc, char **argv)
{
struct mq_attr attr;
mode_t mode;
int flag, retval;
struct sigevent se;
struct sigaction sa;
if (argc != 2)
{
printf ("\nUSAGE: %s file_name\n\n", argv[0]);
exit (1);
}
else
{
/* open the message queue for reading */
flag = (O_CREAT | O_RDONLY | O_NONBLOCK);
mode = S_IRWXU;
attr.mq_maxmsg = 1;
attr.mq_msgsize = sizeof(int);
attr.mq_flags = 0;
rd_q = mq_open(rd_name, flag, mode, &attr);
if (rd_q == (mqd_t) -1)
{
printf("errno = %i\n", errno);
exit(1);
}
/* open the message queue for writing */
flag = (O_CREAT | O_WRONLY);
attr.mq_maxmsg = 10;
attr.mq_msgsize = MESSAGE_SIZE;
attr.mq_flags = 0;
wr_q = mq_open(wr_name, flag, mode, &attr);
if (wr_q == (mqd_t) -1)
{
printf("errno = %i\n", errno);
exit(1);
}
/* setup signal handler for reading from the client */
sa.sa_sigaction = request_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
sigaction(SIGRTMIN, &sa, NULL);
se.sigev_notify = SIGEV_SIGNAL;
se.sigev_signo = SIGRTMIN;
se.sigev_value.sival_int = 0; /* not really used */
/***** the next line will hang and reset the workstation *****/
retval = mq_notify(rd_q, &se);
if (retval == -1)
{
printf("mq_notify errno = %i\n", errno);
exit(1);
}
/* open the input file for reading */
fd = open(argv[1], O_RDONLY);
if (fd == -1)
{
perror(argv[1]);
exit(1);
}
while (1)
{
pause();
}
}
close(fd);
exit(0);
}
/***** sample program ends here *****/