Hello,

I've stumbled upon a weird problem. Long story short, I try to open
fifo two times, once O_WRONLY and once O_RDONLY, both in separate
threads - but on process. Unfortunately both threads are locked in
open() functions.

I prepared very small program that reproduces this problem for me,
please see attached file and note that there is no error handling
for readability.

!!! Also note, this program may get stuck in D state,
and you won't be able to SIGKILL it.

Anyone got any idea why is this happening? Is something wrong with
my code? It works properly on netbsd, freebsd, aix, hpux and linux.

I don't know what info exactly you might need, but here is uname,
it's almost clean system, I didn't make much changes, and
especially not in the core.

# uname -a
OpenBSD bbs-i686-builder-openbsd.kurwinet.pl 6.2 GENERIC#163 i386

Output of program on openbsd
$ ./a.out
opening ./test-fifo O_WRONLY
opening ./test-fifo O_RDONLY

and on linux
$ ./a.out
opening /tmp/test-fifo O_WRONLY
opening /tmp/test-fifo O_RDONLY
opened /tmp/test-fifo O_RDONLY
opened /tmp/test-fifo O_WRONLY
producer read: test message

-- 
Best Regards
/* test of unix fifo
 *
 * compile:
 * gcc fifo.c -pthread
 */

#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

static const char *fifo_path = "/tmp/test-fifo";
static const char *str = "test message";

void *consumer(void *arg)
{
	int fd;

	printf("opening %s O_WRONLY\n", fifo_path);
	fd = open(fifo_path, O_WRONLY);
	printf("opened %s O_WRONLY\n", fifo_path);

	write(fd, str, strlen(str));
	close(fd);
	return NULL;
}

void *producer(void *arg)
{
	int fd;
	char buf[16] = {0};

	printf("opening %s O_RDONLY\n", fifo_path);
	fd = open(fifo_path, O_RDONLY);
	printf("opened %s O_RDONLY\n", fifo_path);

	read(fd, buf, strlen(str));
	printf("producer read: %s\n", buf);
	close(fd);
	return NULL;
}

int main(void)
{
	pthread_t consumer_t;
	pthread_t producer_t;

	unlink(fifo_path);
	mkfifo(fifo_path, 0777);

	pthread_create(&consumer_t, NULL, consumer, NULL);
	pthread_create(&producer_t, NULL, producer, NULL);

	pthread_join(producer_t, NULL);
	pthread_join(consumer_t, NULL);

	return 0;
}

Reply via email to