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