From 1b9cba59c38702b6bcdec116591d3c7191ea7ad7 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 14 Jun 2006 20:19:10 +0000 Subject: [PATCH] * 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. --- winsup/cygwin/ChangeLog | 13 ++++++++++++ winsup/cygwin/fhandler.h | 1 + winsup/cygwin/fhandler_socket.cc | 36 +++++++++++++++++++++++++++++++- 3 files changed, 49 insertions(+), 1 deletion(-) 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 + + * 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 * 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; -- 2.43.5