Extend and rename wxSocketImpl::UnblockAndRegisterWithEventLoop()

In addition to unblocking and registering the socket, also support using
this function to make the socket blocking and unregistering it from the
event loop, if its flags include wxSOCKET_BLOCK.

This was already half-done by wxMSW, which took wxSOCKET_BLOCK presence
into account in its implementation, but not by the Unix implementation.
Now do it under all platforms, as this will be useful for switching a
previously non-blocking socket to blocking mode.

Finally, rename the function to better reflect what it really does.

See #12886.
This commit is contained in:
Vadim Zeitlin 2019-11-20 18:55:51 +01:00
parent e0102c2396
commit 51ea713826
4 changed files with 18 additions and 12 deletions

View File

@ -60,7 +60,7 @@ public:
private:
virtual void DoClose() wxOVERRIDE;
virtual void UnblockAndRegisterWithEventLoop() wxOVERRIDE
virtual void UpdateBlockingState() wxOVERRIDE
{
if ( GetSocketFlags() & wxSOCKET_BLOCK )
{
@ -74,6 +74,9 @@ private:
// would result in data races and other unpleasantness.
wxIoctlSocketArg_t trueArg = 1;
ioctlsocket(m_fd, FIONBIO, &trueArg);
// Uninstall it in case it was installed before.
wxSocketManager::Get()->Uninstall_Callback(this);
}
else
{

View File

@ -323,9 +323,11 @@ private:
// called by Close() if we have a valid m_fd
virtual void DoClose() = 0;
// put this socket into non-blocking mode and enable monitoring this socket
// as part of the event loop
virtual void UnblockAndRegisterWithEventLoop() = 0;
// Update the socket depending on the presence or absence of wxSOCKET_BLOCK
// in GetSocketFlags(): if it's present, make the socket blocking and
// ensure that we don't get any asynchronous event for it, otherwise put
// it into non-blocking mode and enable monitoring it in the event loop.
virtual void UpdateBlockingState() = 0;
// check that the socket wasn't created yet and that the given address
// (either m_local or m_peer depending on the socket kind) is valid and
@ -350,7 +352,7 @@ private:
}
// apply the options to the (just created) socket and register it with the
// event loop by calling UnblockAndRegisterWithEventLoop()
// event loop by calling UpdateBlockingState()
void PostCreation();
// update local address after binding/connecting

View File

@ -73,12 +73,13 @@ private:
wxCloseSocket(m_fd);
}
virtual void UnblockAndRegisterWithEventLoop() wxOVERRIDE
virtual void UpdateBlockingState() wxOVERRIDE
{
int trueArg = 1;
ioctl(m_fd, FIONBIO, &trueArg);
// Make this int and not bool to allow passing it to ioctl().
const int isBlocking = (GetSocketFlags() & wxSOCKET_BLOCK) != 0;
ioctl(m_fd, FIONBIO, &isBlocking);
EnableEvents();
DoEnableEvents(wxSOCKET_INPUT_FLAG | wxSOCKET_OUTPUT_FLAG, !isBlocking);
}
// enable or disable notifications for socket input/output events

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;
}