+
+    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 unless this was explicitly disabled by
+    // setting wxSOCKET_BLOCK flag
+    wxEventLoopBase *eventLoop;
+    if ( !(m_flags & wxSOCKET_BLOCK) && wxIsMainThread() )
+    {
+        eventLoop = wxEventLoop::GetActive();
+    }
+    else // in worker thread
+    {
+        // We never dispatch messages from threads other than the main one.
+        eventLoop = NULL;
+    }
+
+    // Make sure the events we're interested in are enabled before waiting for
+    // them: this is really necessary here as otherwise this could happen:
+    //  1. DoRead(wxSOCKET_WAITALL) is called
+    //  2. There is nothing to read so DoWait(wxSOCKET_INPUT_FLAG) is called
+    //  3. Some, but not all data appears, wxSocketImplUnix::OnReadWaiting()
+    //     is called and wxSOCKET_INPUT_FLAG events are disabled in it
+    //  4. Because of wxSOCKET_WAITALL we call DoWait() again but the events
+    //     are still disabled and we block forever
+    //
+    // More elegant solution would be nice but for now simply re-enabling the
+    // events here will do
+    m_impl->ReenableEvents(flags & (wxSOCKET_INPUT_FLAG | wxSOCKET_OUTPUT_FLAG));
+
+
+    // Wait until we receive the event we're waiting for or the timeout expires
+    // (but note that we always execute the loop at least once, even if timeout
+    // is 0 as this is used for polling)
+    int rc = 0;
+    for ( bool firstTime = true; !m_interrupt; firstTime = false )
+    {
+        long timeLeft = wxMilliClockToLong(timeEnd - wxGetLocalTimeMillis());
+        if ( timeLeft < 0 )
+        {
+            if ( !firstTime )
+                break;   // timed out
+
+            timeLeft = 0;
+        }
+
+        wxSocketEventFlags events;
+        if ( eventLoop )
+        {
+            // reset them before starting to wait
+            m_eventsgot = 0;
+
+            eventLoop->DispatchTimeout(timeLeft);
+
+            events = m_eventsgot;
+        }
+        else // no event loop or waiting in another thread
+        {
+            // as explained below, we should always check for wxSOCKET_LOST_FLAG
+            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
+        // it, as continuing to wait for anything else after getting it is
+        // pointless
+        if ( events & wxSOCKET_LOST_FLAG )
+        {
+            m_connected = false;
+            m_establishing = false;
+            rc = -1;
+            break;
+        }
+
+        // otherwise mask out the bits we're not interested in
+        events &= flags;
+
+        // Incoming connection (server) or connection established (client)?
+        if ( events & wxSOCKET_CONNECTION_FLAG )
+        {
+            m_connected = true;
+            m_establishing = false;
+            rc = true;
+            break;
+        }
+
+        // Data available or output buffer ready?
+        if ( (events & wxSOCKET_INPUT_FLAG) || (events & wxSOCKET_OUTPUT_FLAG) )
+        {
+            rc = true;
+            break;
+        }
+    }
+
+    return rc;
+}
+
+bool wxSocketBase::Wait(long seconds, long milliseconds)