Hi Ken,

On Thu, 15 May 2025 18:18:26 -0400
Ken Brown wrote:
> Hi Takashi,
> 
> On 5/14/2025 5:29 AM, Takashi Yano via Cygwin wrote:
> > Hi Ken,
> > 
> > I encountered the problem with fifo. The following STC hangs
> > in cygwin while it works in linux.
> > 
> > Perhaps, cygheap->fdtab.lock() causes a deadlock between
> > both open().
> > 
> > Could you please take a look?
> > 
> > #include <unistd.h>
> > #include <pthread.h>
> > #include <sys/stat.h>
> > #include <fcntl.h>
> > 
> > #define fifo1 "/tmp/fifo-test"
> > 
> > void *thr1(void *)
> > {
> >     int fd;
> >     usleep(100000);
> >     fd = open(fifo1, O_WRONLY);
> >     write(fd, "A", 1);
> >     usleep(100000);
> >     close(fd);
> >     return NULL;
> > }
> > 
> > int main()
> > {
> >     int fd;
> >     pthread_t th;
> >     char c;
> >     mkfifo(fifo1, 0600);
> >     pthread_create(&th, NULL, thr1, NULL);
> >     fd = open(fifo1, O_RDONLY);
> >     pthread_join(th, NULL);
> >     read(fd, &c, 1);
> >     write(1, &c, 1);
> >     close(fd);
> >     return 0;
> > }
> > 
> 
> Thanks for the STC.  I can reproduce the problem.  I'll take a look.

Thanks in advance.

I'm not sure it is the right thing, but I found the following patch
solves the issue. What do you think?

diff --git a/winsup/cygwin/local_includes/cygheap.h 
b/winsup/cygwin/local_includes/cygheap.h
index fed87ec2b..7d11fbb37 100644
--- a/winsup/cygwin/local_includes/cygheap.h
+++ b/winsup/cygwin/local_includes/cygheap.h
@@ -604,6 +604,8 @@ class cygheap_fdnew : public cygheap_fdmanip
   {
     if (cygheap->fdtab[fd])
       cygheap->fdtab[fd]->inc_refcnt ();
+    if (locked)
+      cygheap->fdtab.unlock ();
   }
   void operator = (fhandler_base *fh) {cygheap->fdtab[fd] = fh;}
 };
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index c93bf4c95..d6a2c2d3b 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -1472,11 +1472,6 @@ open (const char *unix_path, int flags, ...)
       mode = va_arg (ap, mode_t);
       va_end (ap);
 
-      cygheap_fdnew fd;
-
-      if (fd < 0)
-       __leave;                /* errno already set */
-
       /* When O_PATH is specified in flags, flag bits other than O_CLOEXEC,
         O_DIRECTORY, and O_NOFOLLOW are ignored. */
       if (flags & O_PATH)
@@ -1577,6 +1572,12 @@ open (const char *unix_path, int flags, ...)
       if ((flags & O_TMPFILE) && !fh->pc.isremote ())
        try_to_bin (fh->pc, fh->get_handle (), DELETE,
                    FILE_OPEN_FOR_BACKUP_INTENT);
+
+      cygheap_fdnew fd;
+
+      if (fd < 0)
+       __leave;                /* errno already set */
+
       fd = fh;
       if (fd <= 2)
        set_std_handle (fd);

-- 
Takashi Yano <takashi.y...@nifty.ne.jp>

-- 
Problem reports:      https://cygwin.com/problems.html
FAQ:                  https://cygwin.com/faq/
Documentation:        https://cygwin.com/docs.html
Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple

Reply via email to