]> git.saurik.com Git - wxWidgets.git/commitdiff
our sockets are always non-blocking anyhow so throw away all the code dealing with...
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 27 Dec 2008 17:15:22 +0000 (17:15 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 27 Dec 2008 17:15:22 +0000 (17:15 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57600 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/msw/private/sockmsw.h
include/wx/private/socket.h
include/wx/unix/private/sockunix.h
src/common/socket.cpp
src/msw/sockmsw.cpp
src/unix/sockunix.cpp

index 2490b15482b382b21074bb939639cbca168080b6..13319931cd7a84bd110358d715792c789c7045f0 100644 (file)
@@ -37,14 +37,12 @@ public:
 
     virtual ~wxSocketImplMSW();
 
-    virtual wxSocketImpl *WaitConnection(wxSocketBase& wxsocket);
+    virtual wxSocketError GetLastError() const;
 
-
-    int Read(void *buffer, int size);
-    int Write(const void *buffer, int size);
+    virtual int Read(void *buffer, int size);
+    virtual int Write(const void *buffer, int size);
 
 private:
-    virtual wxSocketError DoHandleConnect(int ret);
     virtual void DoClose();
 
     virtual void UnblockAndRegisterWithEventLoop()
index 078593477ff94481c98e98f11cc8f8b1845292ae..97efcbbc6fbdaf9ad76b4b1b5b4f5667cc049f9c 100644 (file)
@@ -191,7 +191,6 @@ public:
     // set various socket properties: all of those can only be called before
     // creating the socket
     void SetTimeout(unsigned long millisec);
-    void SetNonBlocking(bool non_blocking) { m_non_blocking = non_blocking; }
     void SetReusable() { m_reusable = true; }
     void SetBroadcast() { m_broadcast = true; }
     void DontDoBind() { m_dobind = false; }
@@ -207,12 +206,17 @@ public:
     // accessors
     // ---------
 
+    bool IsServer() const { return m_server; }
+
     GAddress *GetLocal();
     GAddress *GetPeer();
 
     wxSocketError GetError() const { return m_error; }
     bool IsOk() const { return m_error == wxSOCKET_NOERROR; }
 
+    // get the error code corresponding to the last operation
+    virtual wxSocketError GetLastError() const = 0;
+
 
     // creating/closing the socket
     // --------------------------
@@ -235,8 +239,8 @@ public:
     // (notice that DontDoBind() is ignored by this function)
     //
     // this function may return wxSOCKET_WOULDBLOCK in addition to the return
-    // values listed above
-    wxSocketError CreateClient();
+    // values listed above if wait is false
+    wxSocketError CreateClient(bool wait);
 
     // create (and bind unless DontDoBind() had been called) an UDP socket
     // associated with the given local address
@@ -256,15 +260,25 @@ public:
     virtual int Write(const void *buffer, int size) = 0;
 
     // basically a wrapper for select(): returns the condition of the socket,
-    // blocking for not longer than timeout ms for something to become
-    // available
+    // blocking for not longer than timeout if it is specified (otherwise just
+    // poll without blocking at all)
     //
     // flags defines what kind of conditions we're interested in, the return
     // value is composed of a (possibly empty) subset of the bits set in flags
     wxSocketEventFlags Select(wxSocketEventFlags flags,
-                              unsigned long timeout = 0);
+                              const timeval *timeout = NULL);
+
+    // convenient wrapper calling Select() with our default timeout
+    wxSocketEventFlags SelectWithTimeout(wxSocketEventFlags flags)
+    {
+        return Select(flags, &m_timeout);
+    }
 
-    virtual wxSocketImpl *WaitConnection(wxSocketBase& wxsocket) = 0;
+    // just a wrapper for accept(): it is called to create a new wxSocketImpl
+    // corresponding to a new server connection represented by the given
+    // wxSocketBase, returns NULL on error (including immediately if there are
+    // no pending connections as our sockets are non-blocking)
+    wxSocketImpl *Accept(wxSocketBase& wxsocket);
 
 
     // notifications
@@ -286,8 +300,6 @@ public:
     GAddress *m_peer;
     wxSocketError m_error;
 
-    bool m_non_blocking;
-    bool m_server;
     bool m_stream;
     bool m_establishing;
     bool m_reusable;
@@ -301,20 +313,10 @@ public:
 protected:
     wxSocketImpl(wxSocketBase& wxsocket);
 
-    // wait until input/output becomes available or m_timeout expires
-    //
-    // returns true if we do have input/output or false on timeout or error
-    // (also sets m_error accordingly)
-    bool BlockForInputWithTimeout()
-        { return DoBlockWithTimeout(wxSOCKET_INPUT_FLAG); }
-    bool BlockForOutputWithTimeout()
-        { return DoBlockWithTimeout(wxSOCKET_OUTPUT_FLAG); }
+    // true if we're a listening stream socket
+    bool m_server;
 
 private:
-    // handle the given connect() return value (which may be 0 or EWOULDBLOCK
-    // or something else)
-    virtual wxSocketError DoHandleConnect(int ret) = 0;
-
     // called by Close() if we have a valid m_fd
     virtual void DoClose() = 0;
 
@@ -351,12 +353,6 @@ private:
     // update local address after binding/connecting
     wxSocketError UpdateLocalAddress();
 
-    // wait for IO on the socket or until timeout expires
-    //
-    // the parameter can be one of wxSOCKET_INPUT/OUTPUT_FLAG (but could be
-    // their combination in the future, hence we take wxSocketEventFlags)
-    bool DoBlockWithTimeout(wxSocketEventFlags flags);
-
 
     // set in ctor and never changed except that it's reset to NULL when the
     // socket is shut down
index a10488848810d9e35c27668ad022579893cadb3a..ac36bb315b299fa13c588e68ce3b3a4535966aa1 100644 (file)
@@ -29,11 +29,12 @@ public:
         m_enabledCallbacks = 0;
     }
 
+    virtual wxSocketError GetLastError() const;
+
     virtual void Shutdown();
-    virtual wxSocketImpl *WaitConnection(wxSocketBase& wxsocket);
 
-    int Read(void *buffer, int size);
-    int Write(const void *buffer, int size);
+    virtual int Read(void *buffer, int size);
+    virtual int Write(const void *buffer, int size);
 
     // wxFDIOHandler methods
     virtual void OnReadWaiting();
@@ -49,7 +50,6 @@ public:
     int GetEnabledCallbacks() const { return m_enabledCallbacks; }
 
 private:
-    virtual wxSocketError DoHandleConnect(int ret);
     virtual void DoClose()
     {
         wxSocketManager * const manager = wxSocketManager::Get();
@@ -151,7 +151,7 @@ protected:
 
             case wxSOCKET_CONNECTION:
                 // FIXME: explain this?
-                return socket->m_server ? FD_INPUT : FD_OUTPUT;
+                return socket->IsServer() ? FD_INPUT : FD_OUTPUT;
         }
     }
 
index a02d9e968218b8d5b9a5f01cd131a79b156c31a8..222ca488ba8a6e481be275ba4ad40e94d9f42beb 100644 (file)
@@ -102,31 +102,6 @@ public:
     DECLARE_NO_COPY_CLASS(wxSocketState)
 };
 
-// Conditionally make the socket non-blocking for the lifetime of this object.
-class wxSocketUnblocker
-{
-public:
-    wxSocketUnblocker(wxSocketImpl *socket, bool unblock = true)
-        : m_impl(socket),
-          m_unblock(unblock)
-    {
-        if ( m_unblock )
-            m_impl->SetNonBlocking(true);
-    }
-
-    ~wxSocketUnblocker()
-    {
-        if ( m_unblock )
-            m_impl->SetNonBlocking(false);
-    }
-
-private:
-    wxSocketImpl * const m_impl;
-    bool m_unblock;
-
-    DECLARE_NO_COPY_CLASS(wxSocketUnblocker)
-};
-
 // ============================================================================
 // wxSocketManager
 // ============================================================================
@@ -185,7 +160,6 @@ wxSocketImpl::wxSocketImpl(wxSocketBase& wxsocket)
     m_error           = wxSOCKET_NOERROR;
     m_server          = false;
     m_stream          = true;
-    m_non_blocking    = false;
 
     SetTimeout(wxsocket.GetTimeout() * 1000);
 
@@ -248,8 +222,8 @@ void wxSocketImpl::PostCreation()
     if ( m_initialSendBufferSize >= 0 )
         SetSocketOption(SO_SNDBUF, m_initialSendBufferSize);
 
-    // FIXME: shouldn't we check for m_non_blocking here? as it is now, all our
-    //        sockets are non-blocking
+    // we always put our sockets in unblocked mode and handle blocking
+    // ourselves in DoRead/Write() if wxSOCKET_WAITALL is specified
     UnblockAndRegisterWithEventLoop();
 }
 
@@ -309,7 +283,7 @@ wxSocketError wxSocketImpl::CreateServer()
     return UpdateLocalAddress();
 }
 
-wxSocketError wxSocketImpl::CreateClient()
+wxSocketError wxSocketImpl::CreateClient(bool wait)
 {
     if ( !PreCreateCheck(m_peer) )
         return m_error;
@@ -318,8 +292,8 @@ wxSocketError wxSocketImpl::CreateClient()
 
     if ( m_fd == INVALID_SOCKET )
     {
-      m_error = wxSOCKET_IOERR;
-      return wxSOCKET_IOERR;
+        m_error = wxSOCKET_IOERR;
+        return wxSOCKET_IOERR;
     }
 
     PostCreation();
@@ -335,9 +309,34 @@ wxSocketError wxSocketImpl::CreateClient()
         }
     }
 
-    // Connect to the peer and handle the EWOULDBLOCK return value in
-    // platform-specific code
-    return DoHandleConnect(connect(m_fd, m_peer->m_addr, m_peer->m_len));
+    // Do connect now
+    int rc = connect(m_fd, m_peer->m_addr, m_peer->m_len);
+    if ( rc == SOCKET_ERROR )
+    {
+        wxSocketError err = GetLastError();
+        if ( err == wxSOCKET_WOULDBLOCK )
+        {
+            m_establishing = true;
+
+            // block waiting for connection if we should (otherwise just return
+            // wxSOCKET_WOULDBLOCK to the caller)
+            if ( wait )
+            {
+                err = SelectWithTimeout(wxSOCKET_CONNECTION_FLAG)
+                        ? wxSOCKET_NOERROR
+                        : wxSOCKET_TIMEDOUT;
+                m_establishing = false;
+            }
+        }
+
+        m_error = err;
+    }
+    else // connected
+    {
+        m_error = wxSOCKET_NOERROR;
+    }
+
+    return m_error;
 }
 
 
@@ -374,6 +373,26 @@ wxSocketError wxSocketImpl::CreateUDP()
     return wxSOCKET_NOERROR;
 }
 
+wxSocketImpl *wxSocketImpl::Accept(wxSocketBase& wxsocket)
+{
+    wxSockAddr from;
+    WX_SOCKLEN_T fromlen = sizeof(from);
+    const int fd = accept(m_fd, &from, &fromlen);
+
+    if ( fd == INVALID_SOCKET )
+        return NULL;
+
+    wxSocketImpl * const sock = Create(wxsocket);
+    sock->m_fd = fd;
+
+    sock->m_peer = GAddress_new();
+    _GAddress_translate_from(sock->m_peer, &from, fromlen);
+
+    sock->UnblockAndRegisterWithEventLoop();
+
+    return sock;
+}
+
 
 void wxSocketImpl::Close()
 {
@@ -517,38 +536,6 @@ GAddress *wxSocketImpl::GetPeer()
   return NULL;
 }
 
-bool wxSocketImpl::DoBlockWithTimeout(wxSocketEventFlags flags)
-{
-    if ( !m_non_blocking )
-    {
-        fd_set fds;
-        wxFD_ZERO(&fds);
-        wxFD_SET(m_fd, &fds);
-
-        fd_set
-            *readfds = flags & wxSOCKET_INPUT_FLAG ? &fds : NULL,
-            *writefds = flags & wxSOCKET_OUTPUT_FLAG ? &fds : NULL;
-
-        // make a copy as it can be modified by select()
-        struct timeval tv = m_timeout;
-        int ret = select(m_fd + 1, readfds, writefds, NULL, &tv);
-
-        switch ( ret )
-        {
-            case 0:
-                m_error = wxSOCKET_TIMEDOUT;
-                return false;
-
-            case -1:
-                m_error = wxSOCKET_IOERR;
-                return false;
-        }
-    }
-    //else: we're non-blocking, never block
-
-    return true;
-}
-
 // ==========================================================================
 // wxSocketBase
 // ==========================================================================
@@ -715,9 +702,6 @@ wxSocketError wxSocketBase::LastError() const
 
 // The following IO operations update m_error and m_lcount:
 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
-//
-// TODO: Should Connect, Accept and AcceptWith update m_error?
-
 bool wxSocketBase::Close()
 {
     // Interrupt pending waits
@@ -773,7 +757,6 @@ wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
     // polling the socket and don't block at all.
     if ( m_flags & wxSOCKET_NOWAIT )
     {
-        wxSocketUnblocker unblock(m_impl);
         int ret = m_impl->Read(buffer, nbytes);
         if ( ret < 0 )
             return 0;
@@ -784,10 +767,8 @@ wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
     {
         for ( ;; )
         {
-            // Wait until socket becomes ready for reading dispatching the GUI
-            // events in the meanwhile unless wxSOCKET_BLOCK was explicitly
-            // specified to disable this.
-            if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForRead() )
+            // Wait until socket becomes ready for reading
+            if ( !WaitForRead() )
                 break;
 
             const int ret = m_impl->Read(buffer, nbytes);
@@ -981,7 +962,6 @@ wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
     wxUint32 total = 0;
     if ( m_flags & wxSOCKET_NOWAIT )
     {
-        wxSocketUnblocker unblock(m_impl);
         const int ret = m_impl->Write(buffer, nbytes);
         if ( ret > 0 )
             total += ret;
@@ -990,7 +970,7 @@ wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
     {
         for ( ;; )
         {
-            if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForWrite() )
+            if ( !WaitForWrite() )
                 break;
 
             const int ret = m_impl->Write(buffer, nbytes);
@@ -1124,7 +1104,7 @@ wxSocketBase& wxSocketBase::Discard()
     and it will return a mask indicating which operations can be performed.
  */
 wxSocketEventFlags wxSocketImpl::Select(wxSocketEventFlags flags,
-                                        unsigned long timeout)
+                                        const timeval *timeout)
 {
   wxSocketEventFlags result = 0;
 
@@ -1132,7 +1112,10 @@ wxSocketEventFlags wxSocketImpl::Select(wxSocketEventFlags flags,
     return (wxSOCKET_LOST_FLAG & flags);
 
   struct timeval tv;
-  SetTimeValFromMS(tv, timeout);
+  if ( timeout )
+      tv = *timeout;
+  else
+      tv.tv_sec = tv.tv_usec = 0;
 
   fd_set readfds;
   fd_set writefds;
@@ -1237,9 +1220,10 @@ wxSocketBase::DoWait(long seconds, long milliseconds, wxSocketEventFlags flags)
     const wxMilliClock_t timeEnd = wxGetLocalTimeMillis() + timeout;
 
     // Get the active event loop which we'll use for the message dispatching
-    // when running in the main thread
+    // when running in the main thread unless this was explicitly disabled by
+    // setting wxSOCKET_BLOCK flag
     wxEventLoopBase *eventLoop;
-    if ( wxIsMainThread() )
+    if ( !(m_flags & wxSOCKET_BLOCK) && wxIsMainThread() )
     {
         eventLoop = wxEventLoop::GetActive();
     }
@@ -1280,7 +1264,9 @@ wxSocketBase::DoWait(long seconds, long milliseconds, wxSocketEventFlags flags)
         else // no event loop or waiting in another thread
         {
             // as explained below, we should always check for wxSOCKET_LOST_FLAG
-            events = m_impl->Select(flags | wxSOCKET_LOST_FLAG, timeLeft);
+            timeval tv;
+            SetTimeValFromMS(tv, timeLeft);
+            events = m_impl->Select(flags | wxSOCKET_LOST_FLAG, &tv);
         }
 
         // always check for wxSOCKET_LOST_FLAG, even if flags doesn't include
@@ -1642,17 +1628,34 @@ wxSocketServer::wxSocketServer(const wxSockAddress& addr_man,
 
 bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
 {
-    if (!m_impl)
+    if ( !m_impl || (m_impl->m_fd == INVALID_SOCKET) || !m_impl->IsServer() )
+    {
+        wxFAIL_MSG( "can only be called for a valid server socket" );
+
+        m_error = wxSOCKET_INVSOCK;
+
         return false;
+    }
 
-    // If wait == false, then the call should be nonblocking.
-    // When we are finished, we put the socket to blocking mode
-    // again.
-    wxSocketUnblocker unblock(m_impl, !wait);
-    sock.m_impl = m_impl->WaitConnection(sock);
+    if ( wait )
+    {
+        // wait until we get a connection
+        if ( !m_impl->SelectWithTimeout(wxSOCKET_INPUT_FLAG) )
+        {
+            m_error = wxSOCKET_TIMEDOUT;
+
+            return false;
+        }
+    }
+
+    sock.m_impl = m_impl->Accept(sock);
 
     if ( !sock.m_impl )
+    {
+        m_error = m_impl->GetLastError();
+
         return false;
+    }
 
     sock.m_type = wxSOCKET_BASE;
     sock.m_connected = true;
@@ -1741,66 +1744,56 @@ wxSocketClient::~wxSocketClient()
 // Connect
 // --------------------------------------------------------------------------
 
-bool wxSocketClient::DoConnect(const wxSockAddress& addr_man,
+bool wxSocketClient::DoConnect(const wxSockAddress& remote,
                                const wxSockAddress* local,
                                bool wait)
 {
-    if (m_impl)
+    if ( m_impl )
     {
-        // Shutdown and destroy the socket
+        // Shutdown and destroy the old socket
         Close();
         delete m_impl;
     }
 
-    m_impl = wxSocketImpl::Create(*this);
     m_connected = false;
     m_establishing = false;
 
-    if (!m_impl)
+    // Create and set up the new one
+    m_impl = wxSocketImpl::Create(*this);
+    if ( !m_impl )
         return false;
 
-    // If wait == false, then the call should be nonblocking. When we are
-    // finished, we put the socket to blocking mode again.
-    wxSocketUnblocker unblock(m_impl, !wait);
-
     // Reuse makes sense for clients too, if we are trying to rebind to the same port
     if (GetFlags() & wxSOCKET_REUSEADDR)
-    {
         m_impl->SetReusable();
-    }
     if (GetFlags() & wxSOCKET_BROADCAST)
-    {
         m_impl->SetBroadcast();
-    }
     if (GetFlags() & wxSOCKET_NOBIND)
-    {
         m_impl->DontDoBind();
-    }
 
-    // If no local address was passed and one has been set, use the one that was Set
-    if (!local && m_localAddress.GetAddress())
-    {
+    // Bind to the local IP address and port, when provided or if one had been
+    // set before
+    if ( !local && m_localAddress.GetAddress() )
         local = &m_localAddress;
-    }
-
-    // Bind to the local IP address and port, when provided
-    if (local)
-    {
-        GAddress* la = local->GetAddress();
 
-        if (la && la->m_addr)
-            m_impl->SetLocal(la);
-    }
+    if ( local )
+        m_impl->SetLocal(local->GetAddress());
 
     m_impl->SetInitialSocketBuffers(m_initialRecvBufferSize, m_initialSendBufferSize);
 
-    m_impl->SetPeer(addr_man.GetAddress());
-    const wxSocketError err = m_impl->CreateClient();
+    m_impl->SetPeer(remote.GetAddress());
+
+    // Finally do create the socket and connect to the peer
+    const wxSocketError err = m_impl->CreateClient(wait);
 
-    if (err != wxSOCKET_NOERROR)
+    if ( err != wxSOCKET_NOERROR )
     {
-        if (err == wxSOCKET_WOULDBLOCK)
+        if ( err == wxSOCKET_WOULDBLOCK )
+        {
+            wxASSERT_MSG( !wait, "shouldn't get this for blocking connect" );
+
             m_establishing = true;
+        }
 
         return false;
     }
@@ -1809,16 +1802,16 @@ bool wxSocketClient::DoConnect(const wxSockAddress& addr_man,
     return true;
 }
 
-bool wxSocketClient::Connect(const wxSockAddress& addr_man, bool wait)
+bool wxSocketClient::Connect(const wxSockAddress& remote, bool wait)
 {
-    return DoConnect(addr_man, NULL, wait);
+    return DoConnect(remote, NULL, wait);
 }
 
-bool wxSocketClient::Connect(const wxSockAddress& addr_man,
+bool wxSocketClient::Connect(const wxSockAddress& remote,
                              const wxSockAddress& local,
                              bool wait)
 {
-    return DoConnect(addr_man, &local, wait);
+    return DoConnect(remote, &local, wait);
 }
 
 bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
index 6bae719a94792a2259907424ea271019a89a9cf3..d7773c0c8a0674e9156a84a265e1d3ee867303dd 100644 (file)
@@ -448,139 +448,22 @@ void wxSocketImplMSW::DoClose()
     closesocket(m_fd);
 }
 
-/*
- *  Waits for an incoming client connection. Returns a pointer to
- *  a wxSocketImpl object, or NULL if there was an error, in which case
- *  the last error field will be updated for the calling wxSocketImpl.
- *
- *  Error codes (set in the calling wxSocketImpl)
- *    wxSOCKET_INVSOCK    - the socket is not valid or not a server.
- *    wxSOCKET_TIMEDOUT   - timeout, no incoming connections.
- *    wxSOCKET_WOULDBLOCK - the call would block and the socket is nonblocking.
- *    wxSOCKET_MEMERR     - couldn't allocate memory.
- *    wxSOCKET_IOERR      - low-level error.
- */
-wxSocketImpl *wxSocketImplMSW::WaitConnection(wxSocketBase& wxsocket)
+wxSocketError wxSocketImplUnix::GetLastError() const
 {
-  wxSocketImpl *connection;
-  wxSockAddr from;
-  WX_SOCKLEN_T fromlen = sizeof(from);
-  wxSocketError err;
-  u_long arg = 1;
-
-  /* Reenable CONNECTION events */
-  m_detected &= ~wxSOCKET_CONNECTION_FLAG;
-
-  /* If the socket has already been created, we exit immediately */
-  if (m_fd == INVALID_SOCKET || !m_server)
-  {
-    m_error = wxSOCKET_INVSOCK;
-    return NULL;
-  }
-
-  /* Create a wxSocketImpl object for the new connection */
-  connection = wxSocketImplMSW::Create(wxsocket);
-
-  if (!connection)
-  {
-    m_error = wxSOCKET_MEMERR;
-    return NULL;
-  }
-
-  /* Wait for a connection (with timeout) */
-  if ( !BlockForInputWithTimeout() )
-  {
-    delete connection;
-    return NULL;
-  }
-
-  connection->m_fd = accept(m_fd, (sockaddr*)&from, &fromlen);
-
-  if (connection->m_fd == INVALID_SOCKET)
-  {
-    if (WSAGetLastError() == WSAEWOULDBLOCK)
-      m_error = wxSOCKET_WOULDBLOCK;
-    else
-      m_error = wxSOCKET_IOERR;
-
-    delete connection;
-    return NULL;
-  }
-
-  /* Initialize all fields */
-  connection->m_server   = false;
-  connection->m_stream   = true;
-
-  /* Setup the peer address field */
-  connection->m_peer = GAddress_new();
-  if (!connection->m_peer)
-  {
-    delete connection;
-    m_error = wxSOCKET_MEMERR;
-    return NULL;
-  }
-  err = _GAddress_translate_from(connection->m_peer, (sockaddr*)&from, fromlen);
-  if (err != wxSOCKET_NOERROR)
-  {
-    GAddress_destroy(connection->m_peer);
-    delete connection;
-    m_error = err;
-    return NULL;
-  }
-
-  ioctlsocket(connection->m_fd, FIONBIO, (u_long FAR *) &arg);
-  wxSocketManager::Get()->Install_Callback(connection);
-
-  return connection;
-}
-
-wxSocketError wxSocketImplMSW::DoHandleConnect(int ret)
-{
-    // TODO: review this
-    if (ret == SOCKET_ERROR)
+    switch ( WSAGetLastError() )
     {
-        int err = WSAGetLastError();
+        case 0:
+            return wxSOCKET_NOERROR;
 
-        /* If connect failed with EWOULDBLOCK and the wxSocketImpl object
-         * is in blocking mode, we select() for the specified timeout
-         * checking for writability to see if the connection request
-         * completes.
-         */
-        if ((err == WSAEWOULDBLOCK) && (!m_non_blocking))
-        {
-            err = Connect_Timeout();
+        case WSAENOTSOCK:
+            return wxSOCKET_INVSOCK;
 
-            if (err != wxSOCKET_NOERROR)
-            {
-                Close();
-                /* m_error is set in Connect_Timeout */
-            }
-
-            return (wxSocketError) err;
-        }
-
-        /* If connect failed with EWOULDBLOCK and the wxSocketImpl object
-         * is set to nonblocking, we set m_error to wxSOCKET_WOULDBLOCK
-         * (and return wxSOCKET_WOULDBLOCK) but we don't close the socket;
-         * this way if the connection completes, a wxSOCKET_CONNECTION
-         * event will be generated, if enabled.
-         */
-        if ((err == WSAEWOULDBLOCK) && (m_non_blocking))
-        {
-            m_establishing = true;
-            m_error = wxSOCKET_WOULDBLOCK;
+        case WSAEWOULDBLOCK:
             return wxSOCKET_WOULDBLOCK;
-        }
 
-        /* If connect failed with an error other than EWOULDBLOCK,
-         * then the call to Connect() has failed.
-         */
-        Close();
-        m_error = wxSOCKET_IOERR;
-        return wxSOCKET_IOERR;
+        default:
+            return wxSOCKET_IOERR;
     }
-
-    return wxSOCKET_NOERROR;
 }
 
 /* Generic IO */
@@ -599,12 +482,6 @@ int wxSocketImplMSW::Read(void *buffer, int size)
     return -1;
   }
 
-  /* If the socket is blocking, wait for data (with a timeout) */
-  if ( !BlockForInputWithTimeout() )
-  {
-    return -1;
-  }
-
   /* Read the data */
   if (m_stream)
     ret = Recv_Stream(buffer, size);
@@ -633,10 +510,6 @@ int wxSocketImplMSW::Write(const void *buffer, int size)
     return -1;
   }
 
-  /* If the socket is blocking, wait for writability (with a timeout) */
-  if ( !BlockForOutputWithTimeout() )
-    return -1;
-
   /* Write the data */
   if (m_stream)
     ret = Send_Stream(buffer, size);
index bfe81ba066f73ca7160ba5602c7a0b991ecf929d..60143e73a1aa24fdf423d1216ca9d8cb943e521f 100644 (file)
@@ -424,13 +424,6 @@ struct servent *wxGetservbyname_r(const char *port, const char *protocol,
   return se;
 }
 
-/* debugging helpers */
-#ifdef __GSOCKET_DEBUG__
-#  define SOCKET_DEBUG(args) printf args
-#else
-#  define SOCKET_DEBUG(args)
-#endif /* __GSOCKET_DEBUG__ */
-
 /* static */
 wxSocketImpl *wxSocketImpl::Create(wxSocketBase& wxsocket)
 {
@@ -450,93 +443,22 @@ void wxSocketImplUnix::Shutdown()
     wxSocketImpl::Shutdown();
 }
 
-/*
- *  Waits for an incoming client connection. Returns a pointer to
- *  a wxSocketImplUnix object, or NULL if there was an error, in which case
- *  the last error field will be updated for the calling wxSocketImplUnix.
- *
- *  Error codes (set in the calling wxSocketImplUnix)
- *    wxSOCKET_INVSOCK    - the socket is not valid or not a server.
- *    wxSOCKET_TIMEDOUT   - timeout, no incoming connections.
- *    wxSOCKET_WOULDBLOCK - the call would block and the socket is nonblocking.
- *    wxSOCKET_MEMERR     - couldn't allocate memory.
- *    wxSOCKET_IOERR      - low-level error.
- */
-wxSocketImpl *wxSocketImplUnix::WaitConnection(wxSocketBase& wxsocket)
+wxSocketError wxSocketImplUnix::GetLastError() const
 {
-  wxSockAddr from;
-  WX_SOCKLEN_T fromlen = sizeof(from);
-  wxSocketImpl *connection;
-  wxSocketError err;
-  int arg = 1;
-
-  /* If the socket has already been created, we exit immediately */
-  if (m_fd == INVALID_SOCKET || !m_server)
-  {
-    m_error = wxSOCKET_INVSOCK;
-    return NULL;
-  }
-
-  /* Create a wxSocketImplUnix object for the new connection */
-  connection = wxSocketImplUnix::Create(wxsocket);
-
-  if (!connection)
-  {
-    m_error = wxSOCKET_MEMERR;
-    return NULL;
-  }
-
-  /* Wait for a connection (with timeout) */
-  if ( !BlockForInputWithTimeout() )
-  {
-    delete connection;
-    return NULL;
-  }
-
-  connection->m_fd = accept(m_fd, (sockaddr*)&from, (WX_SOCKLEN_T *) &fromlen);
-
-  /* Reenable CONNECTION events */
-  EnableEvent(wxSOCKET_CONNECTION);
-
-  if (connection->m_fd == INVALID_SOCKET)
-  {
-    if (errno == EWOULDBLOCK)
-      m_error = wxSOCKET_WOULDBLOCK;
-    else
-      m_error = wxSOCKET_IOERR;
-
-    delete connection;
-    return NULL;
-  }
-
-  /* Initialize all fields */
-  connection->m_server   = false;
-  connection->m_stream   = true;
-
-  /* Setup the peer address field */
-  connection->m_peer = GAddress_new();
-  if (!connection->m_peer)
-  {
-    delete connection;
-    m_error = wxSOCKET_MEMERR;
-    return NULL;
-  }
+    switch ( errno )
+    {
+        case 0:
+            return wxSOCKET_NOERROR;
 
-  err = _GAddress_translate_from(connection->m_peer, (sockaddr*)&from, fromlen);
-  if (err != wxSOCKET_NOERROR)
-  {
-    delete connection;
-    m_error = err;
-    return NULL;
-  }
+        case ENOTSOCK:
+            return wxSOCKET_INVSOCK;
 
-#if defined(__EMX__) || defined(__VISAGECPP__)
-  ioctl(connection->m_fd, FIONBIO, (char*)&arg, sizeof(arg));
-#else
-  ioctl(connection->m_fd, FIONBIO, &arg);
-#endif
+        case EINPROGRESS:
+            return wxSOCKET_WOULDBLOCK;
 
-  return connection;
+        default:
+            return wxSOCKET_IOERR;
+    }
 }
 
 void wxSocketImplUnix::DoEnableEvents(bool flag)
@@ -554,70 +476,6 @@ void wxSocketImplUnix::DoEnableEvents(bool flag)
     }
 }
 
-wxSocketError wxSocketImplUnix::DoHandleConnect(int ret)
-{
-  /* We only call EnableEvents() if we know we aren't shutting down the socket.
-   * NB: EnableEvents() needs to be called whether the socket is blocking or
-   * non-blocking, it just shouldn't be called prior to knowing there is a
-   * connection _if_ blocking sockets are being used.
-   * If connect above returns 0, we are already connected and need to make the
-   * call to EnableEvents() now.
-   */
-  if ( m_non_blocking || (ret == 0) )
-    EnableEvents();
-
-  if (ret == -1)
-  {
-    const int err = errno;
-
-    /* If connect failed with EINPROGRESS and the wxSocketImplUnix object
-     * is in blocking mode, we select() for the specified timeout
-     * checking for writability to see if the connection request
-     * completes.
-     */
-    if ((err == EINPROGRESS) && (!m_non_blocking))
-    {
-      if ( !BlockForOutputWithTimeout() )
-      {
-        Close();
-        return wxSOCKET_TIMEDOUT;
-      }
-
-      int error;
-      SOCKOPTLEN_T len = sizeof(error);
-
-      getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*) &error, &len);
-      EnableEvents();
-
-      if (!error)
-        return wxSOCKET_NOERROR;
-    }
-
-    /* If connect failed with EINPROGRESS and the wxSocketImplUnix object
-     * is set to nonblocking, we set m_error to wxSOCKET_WOULDBLOCK
-     * (and return wxSOCKET_WOULDBLOCK) but we don't close the socket;
-     * this way if the connection completes, a wxSOCKET_CONNECTION
-     * event will be generated, if enabled.
-     */
-    if ((err == EINPROGRESS) && (m_non_blocking))
-    {
-      m_establishing = true;
-      m_error = wxSOCKET_WOULDBLOCK;
-      return wxSOCKET_WOULDBLOCK;
-    }
-
-    /* If connect failed with an error other than EINPROGRESS,
-     * then the call to Connect has failed.
-     */
-    Close();
-    m_error = wxSOCKET_IOERR;
-
-    return wxSOCKET_IOERR;
-  }
-
-  return wxSOCKET_NOERROR;
-}
-
 /* Generic IO */
 
 /* Like recv(), send(), ... */
@@ -634,45 +492,34 @@ int wxSocketImplUnix::Read(void *buffer, int size)
   /* Disable events during query of socket status */
   DisableEvent(wxSOCKET_INPUT);
 
-  /* If the socket is blocking, wait for data (with a timeout) */
-  if ( !BlockForInputWithTimeout() )
-  {
-    m_error = wxSOCKET_TIMEDOUT;
-    /* Don't return here immediately, otherwise socket events would not be
-     * re-enabled! */
-    ret = -1;
-  }
-  else
-  {
-    /* Read the data */
-    if (m_stream)
+  /* Read the data */
+  if (m_stream)
       ret = Recv_Stream(buffer, size);
-    else
+  else
       ret = Recv_Dgram(buffer, size);
 
-    /*
-     * If recv returned zero for a TCP socket (if m_stream == NULL, it's an UDP
-     * socket and empty datagrams are possible), then the connection has been
-     * gracefully closed.
-     *
-     * Otherwise, recv has returned an error (-1), in which case we have lost
-     * the socket only if errno does _not_ indicate that there may be more data
-     * to read.
-     */
-    if ((ret == 0) && m_stream)
-    {
+  /*
+   * If recv returned zero for a TCP socket (if m_stream == NULL, it's an UDP
+   * socket and empty datagrams are possible), then the connection has been
+   * gracefully closed.
+   *
+   * Otherwise, recv has returned an error (-1), in which case we have lost
+   * the socket only if errno does _not_ indicate that there may be more data
+   * to read.
+   */
+  if ((ret == 0) && m_stream)
+  {
       /* Make sure wxSOCKET_LOST event gets sent and shut down the socket */
       m_detected = wxSOCKET_LOST_FLAG;
       OnReadWaiting();
       return 0;
-    }
-    else if (ret == -1)
-    {
+  }
+  else if (ret == -1)
+  {
       if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
-        m_error = wxSOCKET_WOULDBLOCK;
+          m_error = wxSOCKET_WOULDBLOCK;
       else
-        m_error = wxSOCKET_IOERR;
-    }
+          m_error = wxSOCKET_IOERR;
   }
 
   /* Enable events again now that we are done processing */
@@ -685,41 +532,27 @@ int wxSocketImplUnix::Write(const void *buffer, int size)
 {
   int ret;
 
-  SOCKET_DEBUG(( "Write #1, size %d\n", size ));
-
   if (m_fd == INVALID_SOCKET || m_server)
   {
     m_error = wxSOCKET_INVSOCK;
     return -1;
   }
 
-  SOCKET_DEBUG(( "Write #2, size %d\n", size ));
-
-  /* If the socket is blocking, wait for writability (with a timeout) */
-  if ( !BlockForOutputWithTimeout() )
-    return -1;
-
-  SOCKET_DEBUG(( "Write #3, size %d\n", size ));
-
   /* Write the data */
   if (m_stream)
     ret = Send_Stream(buffer, size);
   else
     ret = Send_Dgram(buffer, size);
 
-  SOCKET_DEBUG(( "Write #4, size %d\n", size ));
-
   if (ret == -1)
   {
     if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
     {
       m_error = wxSOCKET_WOULDBLOCK;
-      SOCKET_DEBUG(( "Write error WOULDBLOCK\n" ));
     }
     else
     {
       m_error = wxSOCKET_IOERR;
-      SOCKET_DEBUG(( "Write error IOERR\n" ));
     }
 
     /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
@@ -732,8 +565,6 @@ int wxSocketImplUnix::Write(const void *buffer, int size)
     return -1;
   }
 
-  SOCKET_DEBUG(( "Write #5, size %d ret %d\n", size, ret ));
-
   return ret;
 }