OSDN Git Service

Revert code reversion from 2004-04-03. So, revert to async I/O again.
authorcorinna <corinna>
Fri, 7 May 2004 07:51:30 +0000 (07:51 +0000)
committercorinna <corinna>
Fri, 7 May 2004 07:51:30 +0000 (07:51 +0000)
* fhandler.h (status): Add "closed" flag.
(prepare): New method declaration.
(wait): Ditto.
(release): Ditto.
* fhandler_socket.cc: Don't include wsock_event.h.
(fhandler_socket::prepare): New method, moved from wsock_event.
(fhandler_socket::wait): Ditto.
(fhandler_socket::release): New method.
(fhandler_socket::recvfrom): Simplify loop.
(fhandler_socket::recvmsg): Ditto.
(fhandler_socket::sendto): Ditto.
(fhandler_socket::sendmsg): Ditto.
* net.cc: Don't include wsock_event.h.
(wsock_event::prepare): Remove.
(wsock_event::wait): Ditto.
* wsock_event.h: Remove.

winsup/cygwin/ChangeLog
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_socket.cc
winsup/cygwin/net.cc
winsup/cygwin/wsock_event.h [deleted file]

index 62c23f9..6c5d202 100644 (file)
@@ -1,6 +1,22 @@
-2004-05-06  Christopher Faylor  <cgf@alum.bu.edu>
-
-       * 
+2004-05-07  Corinna Vinschen  <corinna@vinschen.de>
+
+       Revert code reversion from 2004-04-03.  So, revert to async I/O again.
+       * fhandler.h (status): Add "closed" flag.
+       (prepare): New method declaration.
+       (wait): Ditto.
+       (release): Ditto.
+       * fhandler_socket.cc: Don't include wsock_event.h.
+       (fhandler_socket::prepare): New method, moved from wsock_event.
+       (fhandler_socket::wait): Ditto.
+       (fhandler_socket::release): New method.
+       (fhandler_socket::recvfrom): Simplify loop.
+       (fhandler_socket::recvmsg): Ditto.
+       (fhandler_socket::sendto): Ditto.
+       (fhandler_socket::sendmsg): Ditto.
+       * net.cc: Don't include wsock_event.h.
+       (wsock_event::prepare): Remove.
+       (wsock_event::wait): Ditto.
+       * wsock_event.h: Remove.
 
 2004-05-06  Christopher Faylor  <cgf@alum.bu.edu>
 
index 3a14434..acdd09f 100644 (file)
@@ -340,14 +340,19 @@ class fhandler_socket: public fhandler_base
     unsigned async_io              : 1; /* async I/O */
     unsigned saw_shutdown_read     : 1; /* Socket saw a SHUT_RD */
     unsigned saw_shutdown_write    : 1; /* Socket saw a SHUT_WR */
+    unsigned closed               : 1;
     unsigned connect_state         : 2;
    public:
     status_flags () :
       async_io (0), saw_shutdown_read (0), saw_shutdown_write (0),
-      connect_state (unconnected)
+      closed (0), connect_state (unconnected)
       {}
   } status;
 
+  bool prepare (HANDLE &event, long event_mask);
+  int wait (HANDLE event);
+  void release (HANDLE event);
+
  public:
   fhandler_socket ();
   ~fhandler_socket ();
@@ -357,6 +362,7 @@ class fhandler_socket: public fhandler_base
   IMPLEMENT_STATUS_FLAG (bool, async_io)
   IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_read)
   IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_write)
+  IMPLEMENT_STATUS_FLAG (bool, closed)
   IMPLEMENT_STATUS_FLAG (conn_state, connect_state)
 
   int bind (const struct sockaddr *name, int namelen);
index 5016700..dedbd34 100644 (file)
@@ -30,7 +30,6 @@
 #include "dtable.h"
 #include "cygheap.h"
 #include "sigproc.h"
-#include "wsock_event.h"
 #include "cygthread.h"
 #include "select.h"
 #include <unistd.h>
@@ -695,6 +694,95 @@ fhandler_socket::getpeername (struct sockaddr *name, int *namelen)
   return res;
 }
 
+bool
+fhandler_socket::prepare (HANDLE &event, long event_mask)
+{
+  WSASetLastError (0);
+  closed (false);
+  if ((event = WSACreateEvent ()) == WSA_INVALID_EVENT)
+    {
+      debug_printf ("WSACreateEvent: %E");
+      return false;
+    }
+  if (WSAEventSelect (get_socket (), event, event_mask) == SOCKET_ERROR)
+    {
+      debug_printf ("WSAEventSelect: %E");
+      return false;
+    }
+  return true;
+}
+
+int
+fhandler_socket::wait (HANDLE event)
+{
+  int ret = SOCKET_ERROR;
+  int wsa_err = 0;
+  WSAEVENT ev[2] = { event, signal_arrived };
+  WSANETWORKEVENTS evts;
+
+  switch (WSAWaitForMultipleEvents (2, ev, FALSE, WSA_INFINITE, FALSE))
+    {
+      case WSA_WAIT_EVENT_0:
+       if (!WSAEnumNetworkEvents (get_socket (), event, &evts))
+         {
+           if (!evts.lNetworkEvents)
+             {
+               ret = 0;
+               break;
+             }
+           if (evts.lNetworkEvents & FD_READ)
+             {
+               if (evts.iErrorCode[FD_READ_BIT])
+                 wsa_err = evts.iErrorCode[FD_READ_BIT];
+               else
+                 ret = 0;
+             }
+           else if (evts.lNetworkEvents & FD_WRITE)
+             {
+               if (evts.iErrorCode[FD_WRITE_BIT])
+                 wsa_err = evts.iErrorCode[FD_WRITE_BIT];
+               else
+                 ret = 0;
+             }
+           if (evts.lNetworkEvents & FD_CLOSE)
+             {
+               closed (true);
+               if (!wsa_err)
+                 {
+                   if (evts.iErrorCode[FD_CLOSE_BIT])
+                     wsa_err = evts.iErrorCode[FD_CLOSE_BIT];
+                   else
+                     ret = 0;
+                 }
+             }
+           if (wsa_err)
+             WSASetLastError (wsa_err);
+         }
+       break;
+      case WSA_WAIT_EVENT_0 + 1:
+        WSASetLastError (WSAEINTR);
+       break;
+      default:
+       WSASetLastError (WSAEFAULT);
+       break;
+    }
+  return ret;
+}
+
+void
+fhandler_socket::release (HANDLE event)
+{
+  int last_err = WSAGetLastError ();
+  /* KB 168349: NT4 fails if the event parameter is not NULL. */
+  WSAEventSelect (get_socket (), NULL, 0);
+  unsigned long non_block = 0;
+  if (ioctlsocket (get_socket (), FIONBIO, &non_block))
+    debug_printf ("return to blocking failed: %d", WSAGetLastError ());
+  else
+    WSASetLastError (last_err);
+  WSACloseEvent (event);
+}
+
 int
 fhandler_socket::readv (const struct iovec *const iov, const int iovcnt,
                        ssize_t tot)
@@ -716,7 +804,7 @@ int
 fhandler_socket::recvfrom (void *ptr, size_t len, int flags,
                           struct sockaddr *from, int *fromlen)
 {
-  int res;
+  int res = SOCKET_ERROR;
   DWORD ret;
 
   flags &= MSG_WINMASK;
@@ -728,19 +816,26 @@ fhandler_socket::recvfrom (void *ptr, size_t len, int flags,
     {
       WSABUF wsabuf = { len, (char *) ptr };
 
-      if (is_nonblocking ())
-       res = WSARecvFrom (get_socket (), &wsabuf, 1, &ret, (DWORD *) &flags,
-                          from, fromlen,
-                          NULL, NULL);
+      if (is_nonblocking () || closed () || async_io ())
+       res = WSARecvFrom (get_socket (), &wsabuf, 1, (ret = 0, &ret),
+                          (DWORD *) &flags, from, fromlen, NULL, NULL);
       else
        {
-         wsock_event wsock_evt;
-         res = WSARecvFrom (get_socket (), &wsabuf, 1, &ret, (DWORD *) &flags,
-                            from, fromlen,
-                            wsock_evt.prepare (), NULL);
-
-         if (res == SOCKET_ERROR && WSAGetLastError () == WSA_IO_PENDING)
-           ret = res = wsock_evt.wait (get_socket (), (DWORD *) &flags);
+         HANDLE evt;
+         if (prepare (evt, FD_CLOSE | ((flags & MSG_OOB) ? FD_OOB : FD_READ)))
+           {
+              do
+                {
+                 res = WSARecvFrom (get_socket (), &wsabuf, 1,
+                                    &ret, (DWORD *) &flags,
+                                    from, fromlen, NULL, NULL);
+                }
+              while (res == SOCKET_ERROR
+                     && WSAGetLastError () == WSAEWOULDBLOCK
+                    && !closed ()
+                    && !(res = wait (evt)));
+             release (evt);
+           }
        }
     }
 
@@ -778,7 +873,7 @@ fhandler_socket::recvmsg (struct msghdr *msg, int flags, ssize_t tot)
   struct sockaddr *from = (struct sockaddr *) msg->msg_name;
   int *fromlen = from ? &msg->msg_namelen : NULL;
 
-  int res;
+  int res = SOCKET_ERROR;
 
   if (!winsock2_active)
     {
@@ -845,21 +940,27 @@ fhandler_socket::recvmsg (struct msghdr *msg, int flags, ssize_t tot)
 
       DWORD ret;
 
-      if (is_nonblocking ())
+      if (is_nonblocking () || closed () || async_io ())
        res = WSARecvFrom (get_socket (),
-                          wsabuf, iovcnt, &ret, (DWORD *) &flags,
-                          from, fromlen,
-                          NULL, NULL);
+                          wsabuf, iovcnt, (ret = 0, &ret), (DWORD *) &flags,
+                          from, fromlen, NULL, NULL);
       else
        {
-         wsock_event wsock_evt;
-         res = WSARecvFrom (get_socket (),
-                            wsabuf, iovcnt, &ret, (DWORD *) &flags,
-                            from, fromlen,
-                            wsock_evt.prepare (), NULL);
-
-         if (res == SOCKET_ERROR && WSAGetLastError () == WSA_IO_PENDING)
-           ret = res = wsock_evt.wait (get_socket (), (DWORD *) &flags);
+         HANDLE evt;
+         if (prepare (evt, FD_CLOSE | ((flags & MSG_OOB) ? FD_OOB : FD_READ)))
+           {
+              do
+                {
+                 res = WSARecvFrom (get_socket (), wsabuf, iovcnt,
+                                    &ret, (DWORD *) &flags,
+                                    from, fromlen, NULL, NULL);
+                }
+              while (res == SOCKET_ERROR
+                    && WSAGetLastError () == WSAEWOULDBLOCK
+                    && !closed ()
+                    && !(res = wait (evt)));
+             release (evt);
+           }
        }
 
       if (res == SOCKET_ERROR)
@@ -904,7 +1005,7 @@ fhandler_socket::sendto (const void *ptr, size_t len, int flags,
   if (to && !get_inet_addr (to, tolen, &sin, &tolen))
     return SOCKET_ERROR;
 
-  int res;
+  int res = SOCKET_ERROR;
   DWORD ret;
 
   if (!winsock2_active)
@@ -915,21 +1016,29 @@ fhandler_socket::sendto (const void *ptr, size_t len, int flags,
     {
       WSABUF wsabuf = { len, (char *) ptr };
 
-      if (is_nonblocking ())
-       res = WSASendTo (get_socket (), &wsabuf, 1, &ret,
+      if (is_nonblocking () || closed () || async_io ())
+       res = WSASendTo (get_socket (), &wsabuf, 1, (ret = 0, &ret),
                         flags & MSG_WINMASK,
                         (to ? (const struct sockaddr *) &sin : NULL), tolen,
                         NULL, NULL);
       else
        {
-         wsock_event wsock_evt;
-         res = WSASendTo (get_socket (), &wsabuf, 1, &ret,
-                          flags & MSG_WINMASK,
-                          (to ? (const struct sockaddr *) &sin : NULL), tolen,
-                          wsock_evt.prepare (), NULL);
-
-         if (res == SOCKET_ERROR && WSAGetLastError () == WSA_IO_PENDING)
-           ret = res = wsock_evt.wait (get_socket (), (DWORD *) &flags);
+         HANDLE evt;
+         if (prepare (evt, FD_CLOSE | FD_WRITE))
+           {
+             do 
+               {
+                 res = WSASendTo (get_socket (), &wsabuf, 1, &ret,
+                                  flags & MSG_WINMASK,
+                                  (to ? (const struct sockaddr *) &sin : NULL),
+                                  tolen, NULL, NULL);
+               }
+             while (res == SOCKET_ERROR
+                    && WSAGetLastError () == WSAEWOULDBLOCK
+                    && !(res = wait (evt))
+                    && !closed ());
+             release (evt);
+           }
        }
     }
 
@@ -969,7 +1078,7 @@ fhandler_socket::sendmsg (const struct msghdr *msg, int flags, ssize_t tot)
   struct iovec *const iov = msg->msg_iov;
   const int iovcnt = msg->msg_iovlen;
 
-  int res;
+  int res = SOCKET_ERROR;
 
   if (!winsock2_active)
     {
@@ -1038,21 +1147,28 @@ fhandler_socket::sendmsg (const struct msghdr *msg, int flags, ssize_t tot)
 
       DWORD ret;
 
-      if (is_nonblocking ())
-       res = WSASendTo (get_socket (), wsabuf, iovcnt, &ret, flags,
-                        (struct sockaddr *) msg->msg_name,
-                        msg->msg_namelen,
-                        NULL, NULL);
+      if (is_nonblocking () || closed () || async_io ())
+       res = WSASendTo (get_socket (), wsabuf, iovcnt, (ret = 0, &ret),
+                        flags, (struct sockaddr *) msg->msg_name,
+                        msg->msg_namelen, NULL, NULL);
       else
        {
-         wsock_event wsock_evt;
-         res = WSASendTo (get_socket (), wsabuf, iovcnt, &ret, flags,
-                          (struct sockaddr *) msg->msg_name,
-                          msg->msg_namelen,
-                          wsock_evt.prepare (), NULL);
-
-         if (res == SOCKET_ERROR && WSAGetLastError () == WSA_IO_PENDING)
-           ret = res = wsock_evt.wait (get_socket (), (DWORD *) &flags);
+         HANDLE evt;
+         if (prepare (evt, FD_CLOSE | FD_WRITE))
+           {
+              do
+                {
+                 res = WSASendTo (get_socket (), wsabuf, iovcnt,
+                                  &ret, flags,
+                                  (struct sockaddr *) msg->msg_name,
+                                  msg->msg_namelen, NULL, NULL);
+                }
+              while (res == SOCKET_ERROR
+                    && WSAGetLastError () == WSAEWOULDBLOCK
+                    && !(res = wait (evt))
+                    && !closed ());
+             release (evt);
+           }
        }
 
       if (res == SOCKET_ERROR)
index 3de2c0a..58c3a9f 100644 (file)
@@ -35,7 +35,6 @@ details. */
 #include "sigproc.h"
 #include "pinfo.h"
 #include "registry.h"
-#include "wsock_event.h"
 #include "cygtls.h"
 
 extern "C"
@@ -50,61 +49,6 @@ extern "C"
   int sscanf (const char *, const char *, ...);
 }                              /* End of "C" section */
 
-LPWSAOVERLAPPED
-wsock_event::prepare ()
-{
-  LPWSAOVERLAPPED ret = NULL;
-
-  SetLastError (0);
-  if ((event = WSACreateEvent ()) != WSA_INVALID_EVENT)
-    {
-      memset (&ovr, 0, sizeof ovr);
-      ovr.hEvent = event;
-      ret = &ovr;
-    }
-  else if (GetLastError () == ERROR_PROC_NOT_FOUND) /* winsock2 not available */
-    WSASetLastError (0);
-
-  debug_printf ("%d = wsock_event::prepare ()", ret);
-  return ret;
-}
-
-int
-wsock_event::wait (int socket, LPDWORD flags)
-{
-  int ret = SOCKET_ERROR;
-  WSAEVENT ev[2] = { event, signal_arrived };
-  DWORD len;
-
-  switch (WSAWaitForMultipleEvents (2, ev, FALSE, WSA_INFINITE, FALSE))
-    {
-      case WSA_WAIT_EVENT_0:
-       if (WSAGetOverlappedResult (socket, &ovr, &len, FALSE, flags))
-         ret = (int) len;
-       break;
-      case WSA_WAIT_EVENT_0 + 1:
-       if (!CancelIo ((HANDLE) socket))
-         {
-           debug_printf ("CancelIo() %E, fallback to blocking io");
-           WSAGetOverlappedResult (socket, &ovr, &len, TRUE, flags);
-         }
-       else if (WSAGetOverlappedResult (socket, &ovr, &len, FALSE, flags)
-                && len > 0)
-         ret = (int) len;
-       else
-         WSASetLastError (WSAEINTR);
-       break;
-      case WSA_WAIT_FAILED:
-       break;
-      default:                 /* Should be impossible. *LOL* */
-       WSASetLastError (WSAEFAULT);
-       break;
-    }
-  WSACloseEvent (event);
-  event = NULL;
-  return ret;
-}
-
 WSADATA wsadata;
 
 static fhandler_socket *
diff --git a/winsup/cygwin/wsock_event.h b/winsup/cygwin/wsock_event.h
deleted file mode 100644 (file)
index 3f86381..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/* wsock_event.h: Defining the wsock_event class
-
-   Copyright 2002 Red Hat, Inc.
-
-This file is part of Cygwin.
-
-This software is a copyrighted work licensed under the terms of the
-Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
-details. */
-
-#ifndef __WSOCK_EVENT_H__
-#define __WSOCK_EVENT_H__
-
-class wsock_event
-{
-  WSAEVENT             event;
-  WSAOVERLAPPED                ovr;
-public:
-  wsock_event () : event (NULL) {};
-  ~wsock_event ()
-    {
-      if (event)
-       WSACloseEvent (event);
-      event = NULL;
-    };
-
-  /* The methods are implemented in net.cc */
-  LPWSAOVERLAPPED prepare ();
-  int wait (int socket, LPDWORD flags);
-};
-
-#endif /* __WSOCK_EVENT_H__ */