From 51ea713826bffc0db0b7d6ec3ad39a8ea6f947a3 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 20 Nov 2019 18:55:51 +0100 Subject: [PATCH] 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. --- include/wx/msw/private/sockmsw.h | 5 ++++- include/wx/private/socket.h | 10 ++++++---- include/wx/unix/private/sockunix.h | 9 +++++---- src/common/socket.cpp | 6 +++--- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/include/wx/msw/private/sockmsw.h b/include/wx/msw/private/sockmsw.h index b79aa8e094..70844e4742 100644 --- a/include/wx/msw/private/sockmsw.h +++ b/include/wx/msw/private/sockmsw.h @@ -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 { diff --git a/include/wx/private/socket.h b/include/wx/private/socket.h index fe3d3b2df0..2d184acc07 100644 --- a/include/wx/private/socket.h +++ b/include/wx/private/socket.h @@ -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 diff --git a/include/wx/unix/private/sockunix.h b/include/wx/unix/private/sockunix.h index 2e4506bcbc..8b3fc2bbb0 100644 --- a/include/wx/unix/private/sockunix.h +++ b/include/wx/unix/private/sockunix.h @@ -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 diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 23276fb412..3ae69fadd1 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -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; }