* fhandler_fifo.cc (fhandler_fifo::open): Release process lock and grab a

system-wide mutex to prevent a deadlock and a race.
* sync.h (lock_process): Make fhandler_fifo a friend.
* smallprint.c (__small_vsprintf): Cosmetic change.
This commit is contained in:
Christopher Faylor 2006-06-23 00:19:39 +00:00
parent 083f3e4a23
commit 4470d66ddc
4 changed files with 56 additions and 4 deletions

View File

@ -1,3 +1,11 @@
2006-06-22 Christopher Faylor <cgf@timesys.com>
* fhandler_fifo.cc (fhandler_fifo::open): Release process lock and grab
a system-wide mutex to prevent a deadlock and a race.
* sync.h (lock_process): Make fhandler_fifo a friend.
* smallprint.c (__small_vsprintf): Cosmetic change.
2006-06-15 Corinna Vinschen <corinna@vinschen.de>
* cygwin.din: Export __srget_r, __swbuf_r.

View File

@ -1,6 +1,6 @@
/* fhandler_fifo.cc - See fhandler.h for a description of the fhandler classes.
Copyright 2002, 2003, 2004, 2005 Red Hat, Inc.
Copyright 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
This file is part of Cygwin.
@ -141,10 +141,48 @@ out:
return res;
}
#define FIFO_PREFIX "_cygfifo_"
int
fhandler_fifo::open (int flags, mode_t)
{
int res = 1;
char mutex[CYG_MAX_PATH];
char *emutex = mutex + CYG_MAX_PATH;
char *p, *p1;
/* Generate a semi-unique name to associate with this fifo but try to ensure
that it is no larger than CYG_MAX_PATH */
for (p = mutex, p1 = strchr (get_name (), '\0');
--p1 >= get_name () && p < emutex ; p++)
*p = (*p1 == '/') ? '_' : *p1;
strncpy (p, FIFO_PREFIX, emutex - p);
mutex[CYG_MAX_PATH - 1] = '\0';
/* Create a mutex lock access to this fifo to prevent a race by two processes
trying to figure out if they own the fifo or if they should create it. */
HANDLE h = CreateMutex (&sec_none_nih, false, mutex);
if (!h)
{
__seterrno ();
system_printf ("couldn't open fifo mutex '%s', %E", mutex);
res = 0;
goto out;
}
lock_process::locker.release (); /* Since we may be a while, release the
process lock that is held when we
open an fd. */
/* FIXME? Need to wait for signal here?
This shouldn't block for long, but... */
DWORD resw = WaitForSingleObject (h, INFINITE);
lock_process::locker.acquire (); /* Restore the lock */
if (resw != WAIT_OBJECT_0 && resw != WAIT_ABANDONED_0)
{
__seterrno ();
system_printf ("Wait for fifo mutex '%s' failed, %E", mutex);
goto out;
}
set_io_handle (NULL);
set_output_handle (NULL);
@ -174,6 +212,11 @@ fhandler_fifo::open (int flags, mode_t)
}
out:
if (h)
{
ReleaseMutex (h);
CloseHandle (h);
}
debug_printf ("returning %d, errno %d", res, get_errno ());
return res;
}

View File

@ -1,6 +1,6 @@
/* smallprint.c: small print routines for WIN32
Copyright 1996, 1998, 2000, 2001, 2002 Red Hat, Inc.
Copyright 1996, 1998, 2000, 2001, 2002, 2003, 2005, 2006 Red Hat, Inc.
This file is part of Cygwin.

View File

@ -1,6 +1,6 @@
/* sync.h: Header file for cygwin synchronization primitives.
Copyright 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
Written by Christopher Faylor <cgf@cygnus.com>
@ -66,6 +66,7 @@ public:
locker.release ();
}
friend class dtable;
friend class fhandler_fifo;
};
#endif /*_SYNC_H*/