aboutsummaryrefslogtreecommitdiff
path: root/winsup/cygwin
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2003-06-02 17:52:16 +0000
committerCorinna Vinschen <corinna@vinschen.de>2003-06-02 17:52:16 +0000
commit8e13bd144dbee1439bea0d124850c9da73c1c6f6 (patch)
tree544f1b2d475007fee0648fba7c431931d485ca59 /winsup/cygwin
parent418c6236146a7b26b0501a863f99480d990f06cd (diff)
downloadnewlib-8e13bd144dbee1439bea0d124850c9da73c1c6f6.zip
newlib-8e13bd144dbee1439bea0d124850c9da73c1c6f6.tar.gz
newlib-8e13bd144dbee1439bea0d124850c9da73c1c6f6.tar.bz2
* fhandler_socket.cc: Include cygthread.h.
(class sock_event): Remove. (thread_connect): New function. (thread_accept): Ditto. (fhandler_socket::connect): Use cygthread instead of socket event handling for blocking sockets. (fhandler_socket::accept): Ditto.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog14
-rw-r--r--winsup/cygwin/fhandler_socket.cc167
2 files changed, 71 insertions, 110 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 255ab9c..484349e 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,13 @@
+2003-06-02 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc: Include cygthread.h.
+ (class sock_event): Remove.
+ (thread_connect): New function.
+ (thread_accept): Ditto.
+ (fhandler_socket::connect): Use cygthread instead of socket event
+ handling for blocking sockets.
+ (fhandler_socket::accept): Ditto.
+
2003-06-02 Christopher Faylor <cgf@redhat.com>
* fhandler.cc (fhandler_base::write): Correct minor printf formatting
@@ -5,8 +15,8 @@
2003-06-01 Pierre Humblet <pierre.humblet@ieee.org>
- * fhandler_disk_file.cc (fhandler_disk_file::fstat_by_name): Assume
- an existing directory is a root if FindFirstFile fails.
+ * fhandler_disk_file.cc (fhandler_disk_file::fstat_by_name): Assume
+ an existing directory is a root if FindFirstFile fails.
2003-05-30 Christopher Faylor <cgf@redhat.com>
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 23914e4..b2a8ce1 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -32,6 +32,7 @@
#include "cygheap.h"
#include "sigproc.h"
#include "wsock_event.h"
+#include "cygthread.h"
#include <unistd.h>
#define ENTROPY_SOURCE_DEV_UNIT 9
@@ -119,85 +120,29 @@ get_inet_addr (const struct sockaddr *in, int inlen,
}
}
-class sock_event
+struct sock_thread_data
{
- WSAEVENT ev[2];
- SOCKET evt_sock;
- int evt_type_bit;
-
-public:
- sock_event ()
- {
- ev[0] = WSA_INVALID_EVENT;
- ev[1] = signal_arrived;
- }
- ~sock_event ()
- {
- if (ev[0] != WSA_INVALID_EVENT)
- WSACloseEvent (ev[0]);
- }
- void load (SOCKET sock, int type_bit)
- {
- if (!winsock2_active)
- /* Can not wait for signal if winsock2 is not active */
- return;
-
- if (ev[0] == WSA_INVALID_EVENT)
- if ((ev[0] = WSACreateEvent ()) == WSA_INVALID_EVENT)
- return;
-
- evt_sock = sock;
- evt_type_bit = type_bit;
- if (WSAEventSelect (evt_sock, ev[0], 1 << evt_type_bit))
- {
- WSACloseEvent (ev[0]);
- ev[0] = WSA_INVALID_EVENT;
- }
- }
- int wait ()
- {
- WSANETWORKEVENTS sock_event;
- int wait_result;
-
- if (ev[0] == WSA_INVALID_EVENT)
- return 0;
-
- wait_result = WSAWaitForMultipleEvents (2, ev, FALSE, WSA_INFINITE,
- FALSE);
- if (wait_result == WSA_WAIT_EVENT_0)
- WSAEnumNetworkEvents (evt_sock, ev[0], &sock_event);
-
- /* Cleanup, Revert to blocking. */
- WSAEventSelect (evt_sock, ev[0], 0);
- unsigned long nonblocking = 0;
- ioctlsocket (evt_sock, FIONBIO, &nonblocking);
-
- switch (wait_result)
- {
- case WSA_WAIT_EVENT_0:
- if ((sock_event.lNetworkEvents & (1 << evt_type_bit))
- && sock_event.iErrorCode[evt_type_bit])
- {
- WSASetLastError (sock_event.iErrorCode[evt_type_bit]);
- set_winsock_errno ();
- return -1;
- }
- break;
+ int socket;
+ sockaddr *peer;
+ int *len;
+ int ret;
+};
- case WSA_WAIT_EVENT_0 + 1:
- debug_printf ("signal received");
- set_errno (EINTR);
- return 1;
+static DWORD WINAPI
+connect_thread (void *arg)
+{
+ sock_thread_data *std = (sock_thread_data *) arg;
+ std->ret = ::connect (std->socket, std->peer, *std->len);
+ return 0;
+}
- case WSA_WAIT_FAILED:
- default:
- WSASetLastError (WSAEFAULT);
- set_winsock_errno ();
- return -1;
- }
- return 0;
- }
-};
+static DWORD WINAPI
+accept_thread (void *arg)
+{
+ sock_thread_data *std = (sock_thread_data *) arg;
+ std->ret = ::accept (std->socket, std->peer, std->len);
+ return 0;
+}
/**********************************************************************/
/* fhandler_socket */
@@ -575,7 +520,6 @@ out:
int
fhandler_socket::connect (const struct sockaddr *name, int namelen)
{
- sock_event evt;
BOOL interrupted = FALSE;
int res = -1;
BOOL secret_check_failed = FALSE;
@@ -586,26 +530,28 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
if (!get_inet_addr (name, namelen, &sin, &namelen, secret))
return -1;
- if (!is_nonblocking () && !is_connect_pending ())
- evt.load (get_socket (), FD_CONNECT_BIT);
-
- res = ::connect (get_socket (), (sockaddr *) &sin, namelen);
-
- if (res && !is_nonblocking () && !is_connect_pending ()
- && WSAGetLastError () == WSAEWOULDBLOCK)
- switch (evt.wait ())
- {
- case 1: /* Signal */
- WSASetLastError (WSAEINPROGRESS);
+ if (!is_nonblocking ())
+ {
+ sock_thread_data cd = { get_socket (), (sockaddr *) &sin, &namelen, -1 };
+ cygthread *thread = new cygthread (connect_thread, &cd, "connect");
+ HANDLE wait_events[2] = { *thread, signal_arrived };
+ if (WaitForMultipleObjects(2, wait_events, FALSE, INFINITE)
+ != WAIT_OBJECT_0)
+ {
+ /* Signal arrived */
+ thread->terminate_thread ();
interrupted = TRUE;
- break;
- case 0:
- res = 0;
- break;
- default:
- res = -1;
- break;
- }
+ }
+ else
+ {
+ /* connect returned normally */
+ res = cd.ret;
+ thread->detach ();
+ }
+ delete thread;
+ }
+ else
+ res = ::connect (get_socket (), (sockaddr *) &sin, namelen);
if (res)
{
@@ -704,20 +650,25 @@ fhandler_socket::accept (struct sockaddr *peer, int *len)
if (!is_nonblocking ())
{
- sock_event evt;
- evt.load (get_socket (), FD_ACCEPT_BIT);
- switch (evt.wait ())
- {
- case 1: /* Signal */
- return -1;
- case 0:
- break;
- case -1:
- return -1;
+ sock_thread_data ad = { get_socket (), peer, len, -1 };
+ cygthread *thread = new cygthread (accept_thread, &ad, "accept");
+ HANDLE wait_events[2] = { *thread, signal_arrived };
+ if (WaitForMultipleObjects(2, wait_events, FALSE, INFINITE)
+ != WAIT_OBJECT_0)
+ {
+ /* Signal arrived */
+ thread->terminate_thread ();
+ delete thread;
+ set_errno (EINTR);
+ return -1;
}
+ /* accept returned normally */
+ res = ad.ret;
+ thread->detach ();
+ delete thread;
}
-
- res = ::accept (get_socket (), peer, len);
+ else
+ res = ::accept (get_socket (), peer, len);
if ((SOCKET) res == INVALID_SOCKET && WSAGetLastError () == WSAEWOULDBLOCK)
in_progress = TRUE;