* 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.
This commit is contained in:
Corinna Vinschen 2006-06-14 20:19:10 +00:00
parent 6976c28f87
commit 1b9cba59c3
3 changed files with 49 additions and 1 deletions

View File

@ -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> 2006-06-12 Christopher Faylor <cgf@timesys.com>
* fhandler_tty.cc (fhandler_pty_master::close): Always close * fhandler_tty.cc (fhandler_pty_master::close): Always close

View File

@ -381,6 +381,7 @@ class fhandler_mailslot : public fhandler_base
class fhandler_socket: public fhandler_base class fhandler_socket: public fhandler_base
{ {
private: private:
HANDLE accept_mtx;
int addr_family; int addr_family;
int type; int type;
int connect_secret[4]; int connect_secret[4];

View File

@ -127,6 +127,7 @@ get_inet_addr (const struct sockaddr *in, int inlen,
fhandler_socket::fhandler_socket () : fhandler_socket::fhandler_socket () :
fhandler_base (), fhandler_base (),
accept_mtx (NULL),
sun_path (NULL), sun_path (NULL),
status () status ()
{ {
@ -453,6 +454,7 @@ fhandler_socket::dup (fhandler_base *child)
debug_printf ("here"); debug_printf ("here");
fhandler_socket *fhs = (fhandler_socket *) child; fhandler_socket *fhs = (fhandler_socket *) child;
fhs->accept_mtx = NULL;
fhs->addr_family = addr_family; fhs->addr_family = addr_family;
fhs->set_socket_type (get_socket_type ()); fhs->set_socket_type (get_socket_type ());
if (get_addr_family () == AF_LOCAL) if (get_addr_family () == AF_LOCAL)
@ -469,6 +471,17 @@ fhandler_socket::dup (fhandler_base *child)
} }
} }
fhs->connect_state (connect_state ()); 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 /* Since WSADuplicateSocket() fails on NT systems when the process
is currently impersonating a non-privileged account, we revert 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, if (!DuplicateHandle (hMainProc, get_io_handle (), hMainProc, &nh, 0,
FALSE, DUPLICATE_SAME_ACCESS)) FALSE, DUPLICATE_SAME_ACCESS))
{ {
system_printf ("!DuplicateHandle(%x) failed, %E", get_io_handle ()); system_printf ("DuplicateHandle(%x) failed, %E", get_io_handle ());
__seterrno (); __seterrno ();
if (fhs->accept_mtx)
CloseHandle (fhs->accept_mtx);
return -1; return -1;
} }
VerifyHandle (nh); VerifyHandle (nh);
@ -816,6 +831,11 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
int int
fhandler_socket::listen (int backlog) 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); int res = ::listen (get_socket (), backlog);
if (res) if (res)
set_winsock_errno (); set_winsock_errno ();
@ -960,6 +980,16 @@ fhandler_socket::getpeername (struct sockaddr *name, int *namelen)
bool bool
fhandler_socket::prepare (HANDLE &event, long event_mask) 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); WSASetLastError (0);
closed (false); closed (false);
if ((event = WSACreateEvent ()) == WSA_INVALID_EVENT) if ((event = WSACreateEvent ()) == WSA_INVALID_EVENT)
@ -1084,6 +1114,8 @@ fhandler_socket::release (HANDLE event)
debug_printf ("return to blocking failed: %d", WSAGetLastError ()); debug_printf ("return to blocking failed: %d", WSAGetLastError ());
else else
WSASetLastError (last_err); WSASetLastError (last_err);
if (accept_mtx)
ReleaseMutex (accept_mtx);
} }
int int
@ -1456,6 +1488,8 @@ fhandler_socket::close ()
} }
WSASetLastError (0); WSASetLastError (0);
} }
if (!res && accept_mtx)
CloseHandle (accept_mtx);
debug_printf ("%d = fhandler_socket::close()", res); debug_printf ("%d = fhandler_socket::close()", res);
return res; return res;