mq_send()/mq_receive() may never return if used from threads
Christian Franke
Christian.Franke@t-online.de
Fri Jan 17 15:56:59 GMT 2025
Found with 'stress-ng --workload ...':
If mq_receive is called on an empty queue and mq_send is called later
from a different thread, both functions never return and signals
(including SIGKILL) are no longer processed.
Testcase (attached):
$ uname -r
3.5.5-1.x86_64
$ gcc -o mqhang mqhang.c
$ ./mqhang
mq_send...
mq_send = 0
mq_receive...
mq_receive = 8
mq_receive...
mq_send...
[...hangs...]
Problem does not occur if mq_receive() is called from a fork()ed process
instead of a thread.
--
Regards,
Christian
-------------- next part --------------
#include <fcntl.h>
#include <mqueue.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
static void *receiver(void *arg)
{
mqd_t mq = *(mqd_t*)arg;
unsigned prio;
char msg[42];
for (int i = 0; i < 2; i++) {
if (i == 0)
sleep(2);
printf("mq_receive...\n"); fflush(stdout);
ssize_t ret = mq_receive(mq, msg, sizeof(msg), &prio);
printf("mq_receive = %zd\n", ret); fflush(stdout);
}
return NULL;
}
int main()
{
const char mq_name[] = "/mqtest";
struct mq_attr attr = { 0, 10, 42, 0 };
mqd_t mq = mq_open(mq_name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr);
if (mq == (mqd_t)-1) {
perror("mq_open"); return 1;
}
pthread_t t;
if (pthread_create(&t, NULL, receiver, &mq)) {
fprintf(stderr, "pthread_create failed\n"); return 1;
}
const char msg[] = "Message";
for (int i = 0; i < 2; i++) {
if (i == 1)
sleep(5);
printf("mq_send...\n"); fflush(stdout);
int ret = mq_send(mq, msg, sizeof(msg), 0);
printf("mq_send = %d\n", ret); fflush(stdout);
}
pthread_join(t, NULL);
mq_close(mq);
mq_unlink(mq_name); // Fails, see separate post
return 0;
}
More information about the Cygwin
mailing list