X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4f260c9c68b42e6ccc82710efe6ca6e8418e721d..af7e24c33e1e6e00a7687ee965b921dbe60cdb36:/src/common/socket.cpp diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 0bb79b219f..923dff0d49 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -750,36 +750,48 @@ int wxSocketImpl::Write(const void *buffer, int size) // Initialization and shutdown // -------------------------------------------------------------------------- -// FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses -// to m_countInit with a crit section -size_t wxSocketBase::m_countInit = 0; +namespace +{ + +// counts the number of calls to Initialize() minus the number of calls to +// Shutdown(): we don't really need it any more but it was documented that +// Shutdown() must be called the same number of times as Initialize() and using +// a counter helps us to check it +int gs_socketInitCount = 0; + +} // anonymous namespace bool wxSocketBase::IsInitialized() { - return m_countInit > 0; + wxASSERT_MSG( wxIsMainThread(), "unsafe to call from other threads" ); + + return gs_socketInitCount != 0; } bool wxSocketBase::Initialize() { - if ( !m_countInit++ ) + wxCHECK_MSG( wxIsMainThread(), false, + "must be called from the main thread" ); + + if ( !gs_socketInitCount ) { wxSocketManager * const manager = wxSocketManager::Get(); if ( !manager || !manager->OnInit() ) - { - m_countInit--; - return false; - } } + gs_socketInitCount++; + return true; } void wxSocketBase::Shutdown() { - // we should be initialized - wxASSERT_MSG( m_countInit > 0, wxT("extra call to Shutdown()") ); - if ( --m_countInit == 0 ) + wxCHECK_RET( wxIsMainThread(), "must be called from the main thread" ); + + wxCHECK_RET( gs_socketInitCount > 0, "too many calls to Shutdown()" ); + + if ( !--gs_socketInitCount ) { wxSocketManager * const manager = wxSocketManager::Get(); wxCHECK_RET( manager, "should have a socket manager" ); @@ -821,13 +833,15 @@ void wxSocketBase::Init() m_eventmask = m_eventsgot = 0; - if ( !IsInitialized() ) + // when we create the first socket in the main thread we initialize the + // OS-dependent socket stuff: notice that this means that the user code + // needs to call wxSocket::Initialize() itself if the first socket it + // creates is not created in the main thread + if ( wxIsMainThread() ) { - // this Initialize() will be undone by wxSocketModule::OnExit(), all - // the other calls to it should be matched by a call to Shutdown() - if (!Initialize()) + if ( !Initialize() ) { - wxLogError("Cannot initialize wxSocketBase"); + wxLogError(_("Cannot initialize sockets")); } } } @@ -1355,8 +1369,10 @@ wxSocketBase::DoWait(long timeout, wxSocketEventFlags flags) { wxCHECK_MSG( m_impl, -1, "can't wait on invalid socket" ); - // we're never going to become ready if we're not connected (any more) - if ( !m_connected && !m_establishing ) + // we're never going to become ready in a client if we're not connected any + // more (OTOH a server can call this to precisely wait for a connection so + // do wait for it in this case) + if ( !m_impl->IsServer() && !m_connected && !m_establishing ) return -1; // This can be set to true from Interrupt() to exit this function a.s.a.p. @@ -2079,4 +2095,9 @@ wxFORCE_LINK_MODULE( socketiohandler ) wxFORCE_LINK_MODULE( mswsocket ) #endif +// and for OSXManagerSetter in the OS X one +#ifdef __WXMAC__ + wxFORCE_LINK_MODULE( osxsocket ) +#endif + #endif // wxUSE_SOCKETS