Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2006-06-15 00:19:10 +0400
committerCorinna Vinschen <corinna@vinschen.de>2006-06-15 00:19:10 +0400
commit1b9cba59c38702b6bcdec116591d3c7191ea7ad7 (patch)
tree375903e72b8f9b649aaf49e34e1f65cfa7ea3641 /winsup/cygwin
parent6976c28f870d2fb87e12bd5ef879d15115d66db8 (diff)
* fhandler.h (class fhandler_socket): Add private mutex handle
accept_mtx. * fhandler_socket.cc (fhandler_socket::fhandler_socket): Initialize accept_mtx to NULL. (fhandler_socket::dup): Duplicate accept_mtx, if available. (fhandler_socket::listen): Create accept_mtx before trying to listen. (fhandler_socket::prepare): Wait for accept_mtx if available to serialize accepts on the same socket. (fhandler_socket::release): Release accept_mtx. (fhandler_socket::close): Close accept_mtx on successful closesocket.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog13
-rw-r--r--winsup/cygwin/fhandler.h1
-rw-r--r--winsup/cygwin/fhandler_socket.cc36
3 files changed, 49 insertions, 1 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index fb9fb11c6..659f65b48 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,16 @@
+2006-06-14 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.h (class fhandler_socket): Add private mutex handle
+ accept_mtx.
+ * fhandler_socket.cc (fhandler_socket::fhandler_socket): Initialize
+ accept_mtx to NULL.
+ (fhandler_socket::dup): Duplicate accept_mtx, if available.
+ (fhandler_socket::listen): Create accept_mtx before trying to listen.
+ (fhandler_socket::prepare): Wait for accept_mtx if available to
+ serialize accepts on the same socket.
+ (fhandler_socket::release): Release accept_mtx.
+ (fhandler_socket::close): Close accept_mtx on successful closesocket.
+
2006-06-12 Christopher Faylor <cgf@timesys.com>
* fhandler_tty.cc (fhandler_pty_master::close): Always close
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index cd0ee570c..a78ae48a0 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -381,6 +381,7 @@ class fhandler_mailslot : public fhandler_base
class fhandler_socket: public fhandler_base
{
private:
+ HANDLE accept_mtx;
int addr_family;
int type;
int connect_secret[4];
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index f00ba467d..68a15163b 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -127,6 +127,7 @@ get_inet_addr (const struct sockaddr *in, int inlen,
fhandler_socket::fhandler_socket () :
fhandler_base (),
+ accept_mtx (NULL),
sun_path (NULL),
status ()
{
@@ -453,6 +454,7 @@ fhandler_socket::dup (fhandler_base *child)
debug_printf ("here");
fhandler_socket *fhs = (fhandler_socket *) child;
+ fhs->accept_mtx = NULL;
fhs->addr_family = addr_family;
fhs->set_socket_type (get_socket_type ());
if (get_addr_family () == AF_LOCAL)
@@ -469,6 +471,17 @@ fhandler_socket::dup (fhandler_base *child)
}
}
fhs->connect_state (connect_state ());
+ if (accept_mtx)
+ {
+ if (!DuplicateHandle (hMainProc, accept_mtx, hMainProc, &nh, 0,
+ TRUE, DUPLICATE_SAME_ACCESS))
+ {
+ system_printf ("DuplicateHandle(%x) failed, %E", accept_mtx);
+ __seterrno ();
+ return -1;
+ }
+ fhs->accept_mtx = nh;
+ }
/* Since WSADuplicateSocket() fails on NT systems when the process
is currently impersonating a non-privileged account, we revert
@@ -499,8 +512,10 @@ fhandler_socket::dup (fhandler_base *child)
if (!DuplicateHandle (hMainProc, get_io_handle (), hMainProc, &nh, 0,
FALSE, DUPLICATE_SAME_ACCESS))
{
- system_printf ("!DuplicateHandle(%x) failed, %E", get_io_handle ());
+ system_printf ("DuplicateHandle(%x) failed, %E", get_io_handle ());
__seterrno ();
+ if (fhs->accept_mtx)
+ CloseHandle (fhs->accept_mtx);
return -1;
}
VerifyHandle (nh);
@@ -816,6 +831,11 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
int
fhandler_socket::listen (int backlog)
{
+ if (!accept_mtx && !(accept_mtx = CreateMutex (&sec_all, FALSE, NULL)))
+ {
+ set_errno (ENOBUFS);
+ return -1;
+ }
int res = ::listen (get_socket (), backlog);
if (res)
set_winsock_errno ();
@@ -960,6 +980,16 @@ fhandler_socket::getpeername (struct sockaddr *name, int *namelen)
bool
fhandler_socket::prepare (HANDLE &event, long event_mask)
{
+ if (event_mask == FD_ACCEPT && accept_mtx)
+ {
+ HANDLE obj[2] = { accept_mtx, signal_arrived };
+ if (WaitForMultipleObjects (2, obj, FALSE, INFINITE) != WAIT_OBJECT_0)
+ {
+ debug_printf ("signal_arrived");
+ WSASetLastError (WSAEINTR);
+ return false;
+ }
+ }
WSASetLastError (0);
closed (false);
if ((event = WSACreateEvent ()) == WSA_INVALID_EVENT)
@@ -1084,6 +1114,8 @@ fhandler_socket::release (HANDLE event)
debug_printf ("return to blocking failed: %d", WSAGetLastError ());
else
WSASetLastError (last_err);
+ if (accept_mtx)
+ ReleaseMutex (accept_mtx);
}
int
@@ -1456,6 +1488,8 @@ fhandler_socket::close ()
}
WSASetLastError (0);
}
+ if (!res && accept_mtx)
+ CloseHandle (accept_mtx);
debug_printf ("%d = fhandler_socket::close()", res);
return res;