It was a peachy Sunday, Jan 26 2014, 22:05:25 when Marco Pfatschbacher
<m...@mailq.de> wrote:

> 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.

hmm, it agrees to die here without a fuss...

> Guenther tried to fix this, but it got backed out:
> 
> http://anoncvs.estpak.ee/cgi-bin/cgit/openbsd-src/commit/?id=d8a387a9a09560b65562bc317ad63427bc9cb819
> 

this patch works for me. what exactly was the problem that made it
necessary to revert it?

> 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