]> git.saurik.com Git - wxWidgets.git/commitdiff
do not require a running event loop, even under MSW, for the sockets to work: if...
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 23 Nov 2008 00:11:09 +0000 (00:11 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 23 Nov 2008 00:11:09 +0000 (00:11 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@56923 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/gsocket.h
include/wx/msw/gsockmsw.h
include/wx/unix/gsockunx.h
include/wx/unix/private.h
src/common/socket.cpp
src/msw/gsocket.cpp
src/unix/gsocket.cpp

index a97ef104398bfc1a8eff171621dc892c53b9f33d..a587ece8c0801410c5b4d73418e8b7cd9e2465cd 100644 (file)
@@ -154,6 +154,50 @@ private:
     static GSocketManager *ms_manager;
 };
 
+/*
+    Base class providing functionality common to BSD and Winsock sockets.
+
+    TODO: merge this in wxSocket itself, there is no reason to maintain the
+          separation between wxSocket and GSocket.
+ */
+class GSocketBase
+{
+public:
+    GSocketEventFlags Select(GSocketEventFlags flags);
+
+#ifdef __WINDOWS__
+    SOCKET m_fd;
+#else
+    int m_fd;
+#endif
+
+    bool m_ok;
+    int m_initialRecvBufferSize;
+    int m_initialSendBufferSize;
+
+    GAddress *m_local;
+    GAddress *m_peer;
+    GSocketError m_error;
+
+    bool m_non_blocking;
+    bool m_server;
+    bool m_stream;
+    bool m_establishing;
+    bool m_reusable;
+    bool m_broadcast;
+    bool m_dobind;
+
+#ifdef __WINDOWS__
+    struct timeval m_timeout;
+#else
+    unsigned long m_timeout;
+#endif
+
+    GSocketEventFlags m_detected;
+    GSocketCallback m_cbacks[GSOCK_MAX_EVENT];
+    char *m_data[GSOCK_MAX_EVENT];
+};
+
 #if defined(__WINDOWS__)
     #include "wx/msw/gsockmsw.h"
 #else
@@ -246,6 +290,50 @@ GSocketError _GAddress_Init_UNIX(GAddress *address);
 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path);
 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf);
 
+// standard linux headers produce many warnings when used with icc
+#if defined(__INTELC__) && defined(__LINUX__)
+    inline void wxFD_ZERO(fd_set *fds)
+    {
+        #pragma warning(push)
+        #pragma warning(disable:593)
+        FD_ZERO(fds);
+        #pragma warning(pop)
+    }
+
+    inline void wxFD_SET(int fd, fd_set *fds)
+    {
+        #pragma warning(push, 1)
+        #pragma warning(disable:1469)
+        FD_SET(fd, fds);
+        #pragma warning(pop)
+    }
+
+    inline bool wxFD_ISSET(int fd, fd_set *fds)
+    {
+        #pragma warning(push, 1)
+        #pragma warning(disable:1469)
+        return FD_ISSET(fd, fds);
+        #pragma warning(pop)
+    }
+    inline bool wxFD_CLR(int fd, fd_set *fds)
+    {
+        #pragma warning(push, 1)
+        #pragma warning(disable:1469)
+        return FD_CLR(fd, fds);
+        #pragma warning(pop)
+    }
+#else // !__INTELC__
+    #define wxFD_ZERO(fds) FD_ZERO(fds)
+    #define wxFD_SET(fd, fds) FD_SET(fd, fds)
+    #define wxFD_ISSET(fd, fds) FD_ISSET(fd, fds)
+    #define wxFD_CLR(fd, fds) FD_CLR(fd, fds)
+#endif // __INTELC__/!__INTELC__
+
+// this is for Windows where configure doesn't define this
+#ifndef SOCKOPTLEN_T
+    #define SOCKOPTLEN_T int
+#endif
+
 #endif /* wxUSE_SOCKETS */
 
 #endif /* _WX_GSOCKET_H_ */
index ea5fc11fe4f0dbd5b6ca4e0ca2ba0376b20b3825..36e7bfbb87091560e3282a623d906893ffe7c598 100644 (file)
@@ -24,7 +24,7 @@
 #endif
 
 /* Definition of GSocket */
-class GSocket
+class GSocket : public GSocketBase
 {
 public:
   GSocket();
@@ -47,7 +47,6 @@ public:
   GSocketError SetNonOriented();
   int Read(char *buffer, int size);
   int Write(const char *buffer, int size);
-  GSocketEventFlags Select(GSocketEventFlags flags);
   void SetNonBlocking(bool non_block);
   void SetTimeout(unsigned long millis);
   GSocketError WXDLLIMPEXP_NET GetError();
@@ -73,31 +72,10 @@ protected:
   int Recv_Dgram(char *buffer, int size);
   int Send_Stream(const char *buffer, int size);
   int Send_Dgram(const char *buffer, int size);
-  bool m_ok;
-  int m_initialRecvBufferSize;
-  int m_initialSendBufferSize;
 
 /* TODO: Make these protected */
 public:
-  SOCKET m_fd;
-  GAddress *m_local;
-  GAddress *m_peer;
-  GSocketError m_error;
 
-  /* Attributes */
-  bool m_non_blocking;
-  bool m_server;
-  bool m_stream;
-  bool m_establishing;
-  bool m_reusable;
-  bool m_broadcast;
-  bool m_dobind;
-  struct timeval m_timeout;
-
-  /* Callbacks */
-  GSocketEventFlags m_detected;
-  GSocketCallback m_cbacks[GSOCK_MAX_EVENT];
-  char *m_data[GSOCK_MAX_EVENT];
   int m_msgnumber;
 };
 
index dfbf94e918778714841e255ddbed1a2fc72af9dd..c6459aab095e48f2957ecdadfb32f402a6afddb1 100644 (file)
@@ -13,7 +13,7 @@
 
 class wxGSocketIOHandler;
 
-class GSocket
+class GSocket : public GSocketBase
 {
 public:
     GSocket();
@@ -34,7 +34,6 @@ public:
     GSocketError SetNonOriented();
     int Read(char *buffer, int size);
     int Write(const char *buffer, int size);
-    GSocketEventFlags Select(GSocketEventFlags flags);
     void SetNonBlocking(bool non_block);
     void SetTimeout(unsigned long millisec);
     GSocketError WXDLLIMPEXP_NET GetError();
@@ -66,35 +65,14 @@ protected:
     int Recv_Dgram(char *buffer, int size);
     int Send_Stream(const char *buffer, int size);
     int Send_Dgram(const char *buffer, int size);
-    bool m_ok;
-    int m_initialRecvBufferSize;
-    int m_initialSendBufferSize;
 public:
     /* DFE: We can't protect these data member until the GUI code is updated */
     /* protected: */
-  int m_fd;
   wxGSocketIOHandler *m_handler;
-  GAddress *m_local;
-  GAddress *m_peer;
-  GSocketError m_error;
-
-  bool m_non_blocking;
-  bool m_server;
-  bool m_stream;
-  bool m_establishing;
-  bool m_reusable;
-  bool m_broadcast;
-  bool m_dobind;
-  unsigned long m_timeout;
 
   // true if socket should fire events
   bool m_use_events;
 
-  /* Callbacks */
-  GSocketEventFlags m_detected;
-  GSocketCallback m_cbacks[GSOCK_MAX_EVENT];
-  char *m_data[GSOCK_MAX_EVENT];
-
   // pointer for storing extra (usually GUI-specific) data
   void *m_gui_dependent;
 };
index 3995e70772d914646758d8aae8aa468980d6adcc..627cdb64143bd91e9ea978f693f5064c7800326d 100644 (file)
 #ifndef _WX_UNIX_PRIVATE_H_
 #define _WX_UNIX_PRIVATE_H_
 
-// standard linux headers produce many warnings when used with icc
-#if defined(__INTELC__) && defined(__LINUX__)
-    inline void wxFD_ZERO(fd_set *fds)
-    {
-        #pragma warning(push)
-        #pragma warning(disable:593)
-        FD_ZERO(fds);
-        #pragma warning(pop)
-    }
-
-    inline void wxFD_SET(int fd, fd_set *fds)
-    {
-        #pragma warning(push, 1)
-        #pragma warning(disable:1469)
-        FD_SET(fd, fds);
-        #pragma warning(pop)
-    }
-
-    inline bool wxFD_ISSET(int fd, fd_set *fds)
-    {
-        #pragma warning(push, 1)
-        #pragma warning(disable:1469)
-        return FD_ISSET(fd, fds);
-        #pragma warning(pop)
-    }
-    inline bool wxFD_CLR(int fd, fd_set *fds)
-    {
-        #pragma warning(push, 1)
-        #pragma warning(disable:1469)
-        return FD_CLR(fd, fds);
-        #pragma warning(pop)
-    }
-#else // !__INTELC__
-    #define wxFD_ZERO(fds) FD_ZERO(fds)
-    #define wxFD_SET(fd, fds) FD_SET(fd, fds)
-    #define wxFD_ISSET(fd, fds) FD_ISSET(fd, fds)
-    #define wxFD_CLR(fd, fds) FD_CLR(fd, fds)
-#endif // __INTELC__/!__INTELC__
-
+// this file is currently empty as its original contents was moved to
+// include/wx/gsocket.h but let's keep it for now in case we need it for
+// something again in the future
 
 #endif // _WX_UNIX_PRIVATE_H_
 
index 88ad1f1548cca1b7a5a3f09d701e07c8d76a636e..6de0020de0ec4b13c8382137aa74eceddc6de7fd 100644 (file)
@@ -720,6 +720,112 @@ wxSocketBase& wxSocketBase::Discard()
 // Wait functions
 // --------------------------------------------------------------------------
 
+/* GSocket_Select:
+ *  Polls the socket to determine its status. This function will
+ *  check for the events specified in the 'flags' parameter, and
+ *  it will return a mask indicating which operations can be
+ *  performed. This function won't block, regardless of the
+ *  mode (blocking | nonblocking) of the socket.
+ */
+GSocketEventFlags GSocketBase::Select(GSocketEventFlags flags)
+{
+  assert(this);
+
+  GSocketEventFlags result = 0;
+  fd_set readfds;
+  fd_set writefds;
+  fd_set exceptfds;
+  struct timeval tv;
+
+  if (m_fd == -1)
+    return (GSOCK_LOST_FLAG & flags);
+
+  /* Do not use a static struct, Linux can garble it */
+  tv.tv_sec = 0;
+  tv.tv_usec = 0;
+
+  wxFD_ZERO(&readfds);
+  wxFD_ZERO(&writefds);
+  wxFD_ZERO(&exceptfds);
+  wxFD_SET(m_fd, &readfds);
+  if (flags & GSOCK_OUTPUT_FLAG || flags & GSOCK_CONNECTION_FLAG)
+    wxFD_SET(m_fd, &writefds);
+  wxFD_SET(m_fd, &exceptfds);
+
+  /* Check 'sticky' CONNECTION flag first */
+  result |= GSOCK_CONNECTION_FLAG & m_detected;
+
+  /* If we have already detected a LOST event, then don't try
+   * to do any further processing.
+   */
+  if ((m_detected & GSOCK_LOST_FLAG) != 0)
+  {
+    m_establishing = false;
+    return (GSOCK_LOST_FLAG & flags);
+  }
+
+  /* Try select now */
+  if (select(m_fd + 1, &readfds, &writefds, &exceptfds, &tv) < 0)
+  {
+    /* What to do here? */
+    return (result & flags);
+  }
+
+  /* Check for exceptions and errors */
+  if (wxFD_ISSET(m_fd, &exceptfds))
+  {
+    m_establishing = false;
+    m_detected = GSOCK_LOST_FLAG;
+
+    /* LOST event: Abort any further processing */
+    return (GSOCK_LOST_FLAG & flags);
+  }
+
+  /* Check for readability */
+  if (wxFD_ISSET(m_fd, &readfds))
+  {
+    result |= GSOCK_INPUT_FLAG;
+
+    if (m_server && m_stream)
+    {
+      /* This is a TCP server socket that detected a connection.
+         While the INPUT_FLAG is also set, it doesn't matter on
+         this kind of  sockets, as we can only Accept() from them. */
+      m_detected |= GSOCK_CONNECTION_FLAG;
+    }
+  }
+
+  /* Check for writability */
+  if (wxFD_ISSET(m_fd, &writefds))
+  {
+    if (m_establishing && !m_server)
+    {
+      int error;
+      SOCKOPTLEN_T len = sizeof(error);
+      m_establishing = false;
+      getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
+
+      if (error)
+      {
+        m_detected = GSOCK_LOST_FLAG;
+
+        /* LOST event: Abort any further processing */
+        return (GSOCK_LOST_FLAG & flags);
+      }
+      else
+      {
+        m_detected |= GSOCK_CONNECTION_FLAG;
+      }
+    }
+    else
+    {
+      result |= GSOCK_OUTPUT_FLAG;
+    }
+  }
+
+  return (result | m_detected) & flags;
+}
+
 // All Wait functions poll the socket using GSocket_Select() to
 // check for the specified combination of conditions, until one
 // of these conditions become true, an error occurs, or the
@@ -749,11 +855,6 @@ wxSocketBase::DoWait(long seconds, long milliseconds, wxSocketEventFlags flags)
     if ( wxIsMainThread() )
     {
         eventLoop = wxEventLoop::GetActive();
-
-#ifdef __WXMSW__
-        wxASSERT_MSG( eventLoop,
-                      "Sockets won't work without a running event loop" );
-#endif // __WXMSW__
     }
     else // in worker thread
     {
@@ -808,10 +909,9 @@ wxSocketBase::DoWait(long seconds, long milliseconds, wxSocketEventFlags flags)
 
         if ( eventLoop )
         {
-            // Dispatch the events when we run in the main thread and have an
-            // active event loop: without this sockets don't work at all under
-            // MSW as socket flags are only updated when socket messages are
-            // processed.
+            // This function is only called if wxSOCKET_BLOCK flag was not used
+            // and so we should dispatch the events if there is an event loop
+            // capable of doing it.
             if ( eventLoop->Pending() )
                 eventLoop->Dispatch();
         }
index 8cc501a98ecf917a8cabb42a2dbaa29591ee69a4..1730fc7fc77ac0cbc743ed09d77323fe57ee9ad0 100644 (file)
@@ -776,18 +776,6 @@ int GSocket::Write(const char *buffer, int size)
   return ret;
 }
 
-/* GSocket_Select:
- *  Polls the socket to determine its status. This function will
- *  check for the events specified in the 'flags' parameter, and
- *  it will return a mask indicating which operations can be
- *  performed. This function won't block, regardless of the
- *  mode (blocking | nonblocking) of the socket.
- */
-GSocketEventFlags GSocket::Select(GSocketEventFlags flags)
-{
-  return flags & m_detected;
-}
-
 /* Attributes */
 
 /* GSocket_SetNonBlocking:
index 5cb9783b712bc1f521d96b6bd6fb9e911d52f498..97105ca534aa7a9386492ad38ea7468fa9294b8e 100644 (file)
@@ -1285,112 +1285,6 @@ int GSocket::Write(const char *buffer, int size)
   return ret;
 }
 
-/* GSocket_Select:
- *  Polls the socket to determine its status. This function will
- *  check for the events specified in the 'flags' parameter, and
- *  it will return a mask indicating which operations can be
- *  performed. This function won't block, regardless of the
- *  mode (blocking | nonblocking) of the socket.
- */
-GSocketEventFlags GSocket::Select(GSocketEventFlags flags)
-{
-  assert(this);
-
-  GSocketEventFlags result = 0;
-  fd_set readfds;
-  fd_set writefds;
-  fd_set exceptfds;
-  struct timeval tv;
-
-  if (m_fd == -1)
-    return (GSOCK_LOST_FLAG & flags);
-
-  /* Do not use a static struct, Linux can garble it */
-  tv.tv_sec = 0;
-  tv.tv_usec = 0;
-
-  wxFD_ZERO(&readfds);
-  wxFD_ZERO(&writefds);
-  wxFD_ZERO(&exceptfds);
-  wxFD_SET(m_fd, &readfds);
-  if (flags & GSOCK_OUTPUT_FLAG || flags & GSOCK_CONNECTION_FLAG)
-    wxFD_SET(m_fd, &writefds);
-  wxFD_SET(m_fd, &exceptfds);
-
-  /* Check 'sticky' CONNECTION flag first */
-  result |= GSOCK_CONNECTION_FLAG & m_detected;
-
-  /* If we have already detected a LOST event, then don't try
-   * to do any further processing.
-   */
-  if ((m_detected & GSOCK_LOST_FLAG) != 0)
-  {
-    m_establishing = false;
-    return (GSOCK_LOST_FLAG & flags);
-  }
-
-  /* Try select now */
-  if (select(m_fd + 1, &readfds, &writefds, &exceptfds, &tv) < 0)
-  {
-    /* What to do here? */
-    return (result & flags);
-  }
-
-  /* Check for exceptions and errors */
-  if (wxFD_ISSET(m_fd, &exceptfds))
-  {
-    m_establishing = false;
-    m_detected = GSOCK_LOST_FLAG;
-
-    /* LOST event: Abort any further processing */
-    return (GSOCK_LOST_FLAG & flags);
-  }
-
-  /* Check for readability */
-  if (wxFD_ISSET(m_fd, &readfds))
-  {
-    result |= GSOCK_INPUT_FLAG;
-
-    if (m_server && m_stream)
-    {
-      /* This is a TCP server socket that detected a connection.
-         While the INPUT_FLAG is also set, it doesn't matter on
-         this kind of  sockets, as we can only Accept() from them. */
-      m_detected |= GSOCK_CONNECTION_FLAG;
-    }
-  }
-
-  /* Check for writability */
-  if (wxFD_ISSET(m_fd, &writefds))
-  {
-    if (m_establishing && !m_server)
-    {
-      int error;
-      SOCKOPTLEN_T len = sizeof(error);
-      m_establishing = false;
-      getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
-
-      if (error)
-      {
-        m_detected = GSOCK_LOST_FLAG;
-
-        /* LOST event: Abort any further processing */
-        return (GSOCK_LOST_FLAG & flags);
-      }
-      else
-      {
-        m_detected |= GSOCK_CONNECTION_FLAG;
-      }
-    }
-    else
-    {
-      result |= GSOCK_OUTPUT_FLAG;
-    }
-  }
-
-  return (result | m_detected) & flags;
-}
-
 /* Flags */
 
 /* GSocket_SetNonBlocking: