Merge branch 'sock-event-fix'

Fix unwanted (and sometimes fatal) socket events for blocking sockets
under Unix.

See https://github.com/wxWidgets/wxWidgets/pull/1658
This commit is contained in:
Vadim Zeitlin
2019-12-03 02:25:18 +01:00
5 changed files with 49 additions and 25 deletions

View File

@@ -366,9 +366,9 @@ void wxSocketImpl::PostCreation()
if ( m_initialSendBufferSize >= 0 )
SetSocketOption(SO_SNDBUF, m_initialSendBufferSize);
// we always put our sockets in unblocked mode and handle blocking
// Call this to put our socket in unblocked mode: we'll handle blocking
// ourselves in DoRead/Write() if wxSOCKET_WAITALL is specified
UnblockAndRegisterWithEventLoop();
UpdateBlockingState();
}
wxSocketError wxSocketImpl::UpdateLocalAddress()
@@ -551,7 +551,7 @@ wxSocketImpl *wxSocketImpl::Accept(wxSocketBase& wxsocket)
sock->m_fd = fd;
sock->m_peer = wxSockAddressImpl(from.addr, fromlen);
sock->UnblockAndRegisterWithEventLoop();
sock->UpdateBlockingState();
return sock;
}
@@ -1672,7 +1672,20 @@ void wxSocketBase::SetFlags(wxSocketFlags flags)
"Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
"wxSOCKET_NOWAIT doesn't make sense" );
// Blocking sockets are very different from non-blocking ones and we need
// to [un]register the socket with the event loop if wxSOCKET_BLOCK is
// being [un]set.
const bool
blockChanged = (m_flags & wxSOCKET_BLOCK) != (flags & wxSOCKET_BLOCK);
m_flags = flags;
if ( blockChanged )
{
// Of course, we only do this if we already have the actual socket.
if ( m_impl )
m_impl->UpdateBlockingState();
}
}

View File

@@ -90,17 +90,18 @@ wxSocketError wxSocketImplUnix::GetLastError() const
void wxSocketImplUnix::DoEnableEvents(int flags, bool enable)
{
// No events for blocking sockets, they should be usable from the other
// threads and the events only work for the sockets used by the main one.
if ( GetSocketFlags() & wxSOCKET_BLOCK )
return;
wxSocketManager * const manager = wxSocketManager::Get();
if (!manager)
return;
if ( enable )
{
// We should never try to enable events for the blocking sockets, they
// should be usable from the other threads and the events only work for
// the sockets used by the main one.
wxASSERT_MSG( !(GetSocketFlags() & wxSOCKET_BLOCK),
"enabling events for a blocking socket?" );
if ( flags & wxSOCKET_INPUT_FLAG )
manager->Install_Callback(this, wxSOCKET_INPUT);
if ( flags & wxSOCKET_OUTPUT_FLAG )