diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 03b3b2640..47a4c60c0 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,15 @@ +2001-06-20 Egor Duda + + * fhandler_socket.cc (fhandler_socket::signal_secret_event): New + function. + * fhandler.h: Declare it. + * fhandler_socket.cc (fhandler_socket::create_secret_event): Don't + signal secret event immediately. + (fhandler_socket::check_peer_secret_event): Do it after peer event + was opened. + * net.cc (cygwin_connect): Or if socket is non-blocking. + (cygwin_accept): Ditto. + Mon Jun 18 17:09:25 2001 Christopher Faylor * fhandler_tty.cc (fhandler_tty_slave::init): Revert 2001-06-16 change. diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 856d3d632..c6224d07c 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -397,6 +397,7 @@ public: void get_connect_secret (char*); HANDLE create_secret_event (int *secret = NULL); int check_peer_secret_event (struct sockaddr_in *peer, int *secret = NULL); + void signal_secret_event (); void close_secret_event (); }; diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 288b4f4e5..3ec1ac69e 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -103,14 +103,18 @@ fhandler_socket::create_secret_event (int* secret) secret_event = OpenEvent (EVENT_ALL_ACCESS, FALSE, buf); if (secret_event) - { - ProtectHandle (secret_event); - SetEvent (secret_event); - } + ProtectHandle (secret_event); return secret_event; } +void +fhandler_socket::signal_secret_event () +{ + if (secret_event) + SetEvent (secret_event); +} + void fhandler_socket::close_secret_event () { @@ -136,6 +140,8 @@ fhandler_socket::check_peer_secret_event (struct sockaddr_in* peer, int* secret) ev = OpenEvent (EVENT_ALL_ACCESS, FALSE, buf); } + signal_secret_event (); + if (ev) { DWORD rc = WaitForSingleObject (ev, 10000); diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index 177ae7a2d..bdf679d15 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -739,6 +739,7 @@ cygwin_connect (int fd, { int res; BOOL secret_check_failed = FALSE; + BOOL in_progress = FALSE; fhandler_socket *sock = get (fd); sockaddr_in sin; int secret [4]; @@ -759,18 +760,23 @@ cygwin_connect (int fd, /* Special handling for connect to return the correct error code when called to early on a non-blocking socket. */ if (WSAGetLastError () == WSAEWOULDBLOCK) - WSASetLastError (WSAEINPROGRESS); + { + WSASetLastError (WSAEINPROGRESS); + in_progress = TRUE; + } set_winsock_errno (); } if (sock->get_addr_family () == AF_UNIX) { - if (!res || errno == EINPROGRESS) + if (!res || in_progress) { if (!sock->create_secret_event (secret)) { secret_check_failed = TRUE; } + else if (in_progress) + sock->signal_secret_event (); } if (!secret_check_failed && !res) @@ -887,6 +893,7 @@ cygwin_accept (int fd, struct sockaddr *peer, int *len) { int res = -1; BOOL secret_check_failed = FALSE; + BOOL in_progress = FALSE; sigframe thisframe (mainthread); fhandler_socket *sock = get (fd); @@ -901,18 +908,21 @@ cygwin_accept (int fd, struct sockaddr *peer, int *len) res = accept (sock->get_socket (), peer, len); // can't use a blocking call inside a lock + if ((SOCKET) res == (SOCKET) INVALID_SOCKET && + WSAGetLastError () == WSAEWOULDBLOCK) + in_progress = TRUE; + if (sock->get_addr_family () == AF_UNIX) { - if (((SOCKET) res != (SOCKET) INVALID_SOCKET || - WSAGetLastError () == WSAEWOULDBLOCK)) - { - if (!sock->create_secret_event ()) - { - secret_check_failed = TRUE; - } - } + if ((SOCKET) res != (SOCKET) INVALID_SOCKET || in_progress) + { + if (!sock->create_secret_event ()) + secret_check_failed = TRUE; + else if (in_progress) + sock->signal_secret_event (); + } - if (!secret_check_failed && + if (!secret_check_failed && (SOCKET) res != (SOCKET) INVALID_SOCKET) { if (!sock->check_peer_secret_event ((struct sockaddr_in*) peer))