]> git.saurik.com Git - wxWidgets.git/commitdiff
fix WaitForXXX() to work as before: if the socket is already ready for reading/writin...
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 2 Jan 2009 01:00:40 +0000 (01:00 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 2 Jan 2009 01:00:40 +0000 (01:00 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57725 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/socket.h
src/common/socket.cpp

index 2ce26e53456cb4e03e87f0fe4aa2f0a81828ec6e..791303a2c35181ebc8883cacf13603731198c7e5 100644 (file)
@@ -211,8 +211,19 @@ private:
   // function returns false in this case
   //
   // false is always returned if we returned because of the timeout expiration
+  bool DoWait(long timeout, wxSocketEventFlags flags);
+
+  // a helper calling DoWait() using the same convention as the public
+  // WaitForXXX() functions use, i.e. use our timeout if seconds == -1 or the
+  // specified timeout otherwise
   bool DoWait(long seconds, long milliseconds, wxSocketEventFlags flags);
 
+  // another helper calling DoWait() using our m_timeout
+  bool DoWaitWithTimeout(wxSocketEventFlags flags)
+  {
+      return DoWait(m_timeout*1000, flags);
+  }
+
   // pushback buffer
   void     Pushback(const void *buffer, wxUint32 size);
   wxUint32 GetPushback(void *buffer, wxUint32 size, bool peek);
index 0125402831839b6b13eba19226546566ec3bac9e..bddf312288832c0f84a0b817c6045adf8830304b 100644 (file)
@@ -815,8 +815,8 @@ wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
     {
         // our socket is non-blocking so Read() will return immediately if
         // there is nothing to read yet and it's more efficient to try it first
-        // before entering WaitForRead() which is going to start dispatching
-        // GUI events and, even more importantly, we must do this under Windows
+        // before entering DoWait() which is going to start dispatching GUI
+        // events and, even more importantly, we must do this under Windows
         // where we're not going to get notifications about socket being ready
         // for reading before we read all the existing data from it
         const int ret = m_connected ? m_impl->Read(buffer, nbytes) : 0;
@@ -828,8 +828,10 @@ wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
                 if ( m_flags & wxSOCKET_NOWAIT )
                     break;
 
-                // otherwise wait until the socket becomes ready for reading
-                if ( !WaitForRead() )
+                // otherwise wait until the socket becomes ready for reading or
+                // an error occurs on it
+                if ( !DoWaitWithTimeout(wxSOCKET_INPUT_FLAG |
+                                        wxSOCKET_LOST_FLAG) )
                 {
                     // and exit if the timeout elapsed before it did
                     SetError(wxSOCKET_TIMEDOUT);
@@ -1010,7 +1012,8 @@ wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
                 if ( m_flags & wxSOCKET_NOWAIT )
                     break;
 
-                if ( !WaitForWrite() )
+                if ( !DoWaitWithTimeout(wxSOCKET_OUTPUT_FLAG |
+                                        wxSOCKET_LOST_FLAG) )
                 {
                     SetError(wxSOCKET_TIMEDOUT);
                     break;
@@ -1222,6 +1225,19 @@ wxSocketEventFlags wxSocketImpl::Select(wxSocketEventFlags flags,
 
 bool
 wxSocketBase::DoWait(long seconds, long milliseconds, wxSocketEventFlags flags)
+{
+    // Use either the provided timeout or the default timeout value associated
+    // with this socket.
+    //
+    // TODO: allow waiting forever, see #9443
+    const long timeout = seconds == -1 ? m_timeout * 1000
+                                       : seconds * 1000 + milliseconds;
+
+    return DoWait(timeout, flags);
+}
+
+bool
+wxSocketBase::DoWait(long timeout, wxSocketEventFlags flags)
 {
     wxCHECK_MSG( m_impl, false, "can't wait on invalid socket" );
 
@@ -1233,12 +1249,6 @@ wxSocketBase::DoWait(long seconds, long milliseconds, wxSocketEventFlags flags)
     m_interrupt = false;
 
 
-    // Use either the provided timeout or the default timeout value associated
-    // with this socket.
-    //
-    // TODO: allow waiting forever, see #9443
-    const long timeout = seconds == -1 ? m_timeout * 1000
-                                       : seconds * 1000 + milliseconds;
     const wxMilliClock_t timeEnd = wxGetLocalTimeMillis() + timeout;
 
     // Get the active event loop which we'll use for the message dispatching
@@ -1339,7 +1349,14 @@ bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
     if ( m_unread )
         return true;
 
-    // Note that wxSOCKET_INPUT_LOST has to be explicitly passed to DoWait
+    // Check if the socket is not already ready for input, if it is, there is
+    // no need to start waiting for it (worse, we'll actually never get a
+    // notification about the socket becoming ready if it is already under
+    // Windows)
+    if ( m_impl->Select(wxSOCKET_INPUT_FLAG) )
+        return true;
+
+    // Note that wxSOCKET_LOST_FLAG has to be explicitly passed to DoWait
     // because of the semantics of WaitForRead: a return value of true means
     // that a Read call will return immediately, not that there is
     // actually data to read.
@@ -1349,6 +1366,9 @@ bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
 
 bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
 {
+    if ( m_impl->Select(wxSOCKET_OUTPUT_FLAG) )
+        return true;
+
     return DoWait(seconds, milliseconds, wxSOCKET_OUTPUT_FLAG | wxSOCKET_LOST_FLAG);
 }