On Sun, Jan 26, 2014 at 03:44:14PM -0500, ido...@gmail.com wrote:
> Hi misc@,
> From http://marc.info/?l=openbsd-cvs&m=133217901415880&w=2
> 
> "The ``sleep until we have a writer'' behaviour of an open() on a fifo
> does so with the file descriptor table locked, so if we are waiting for
> another thread to be our writer we will hang forever.
> 
> Found this using zotero and firefox."
> 
> This behavior indeed hangs latest FF+Zotero. Is it fixable?
 

I've been running into this recently myself.
What makes this worse, is that the process isn't even killable.
Guenther tried to fix this, but it got backed out:

http://anoncvs.estpak.ee/cgi-bin/cgit/openbsd-src/commit/?id=d8a387a9a09560b65562bc317ad63427bc9cb819

I was trying to look into this, but ran out of time :-(

A workaround might be to patch either zotero or firefox, to
open the fifo with O_RDWR instead of O_WRONLY.
This way it won't block in open().

Here's my test program to trigger the issue.

#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#include <sys/types.h>

void *
open_thread(void *threadid)
{
        int fd;

        sleep(1); /* delay to let main run into FIFO open first */

        printf("before open in thread\n");

        if ((fd = open("/tmp/regfile", O_CREAT| O_RDWR, 0600)) < 0)
                err(1, "open");

        printf("after open in thread\n");

        close(fd);
        pthread_exit(NULL);
}

int
main(int argc, char** argv)
{
        int fd;
        pthread_t thread;
        long t;

        if (pthread_create(&thread, NULL, open_thread, (void *)t) != 0)
                err(1, "pthread_create");

        mkfifo("/tmp/block.fifo", 0600);

        printf("before blocking open in main\n");

        if ((fd = open("/tmp/block.fifo", O_WRONLY)) < 0)
                err(1, "open");
        
        printf("after blocking open in main\n");

        close(fd);
        pthread_exit(NULL);
        exit(0);
}

Reply via email to