X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9a83f860948059b0273b5cc6d9e43fadad3ebfca..ec2d6790e96921e031555eac66bb924b0eb6c1a0:/src/common/socket.cpp diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 09324181ae..923dff0d49 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -533,7 +533,14 @@ wxSocketImpl *wxSocketImpl::Accept(wxSocketBase& wxsocket) if ( fd == INVALID_SOCKET ) return NULL; - wxSocketImpl * const sock = Create(wxsocket); + wxSocketManager * const manager = wxSocketManager::Get(); + if ( !manager ) + return NULL; + + wxSocketImpl * const sock = manager->CreateSocket(wxsocket); + if ( !sock ) + return NULL; + sock->m_fd = fd; sock->m_peer = wxSockAddressImpl(from.addr, fromlen); @@ -743,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" ); @@ -814,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")); } } } @@ -1348,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. @@ -1739,7 +1762,8 @@ wxSocketServer::wxSocketServer(const wxSockAddress& addr, { wxLogTrace( wxTRACE_Socket, wxT("Opening wxSocketServer") ); - m_impl = wxSocketImpl::Create(*this); + wxSocketManager * const manager = wxSocketManager::Get(); + m_impl = manager ? manager->CreateSocket(*this) : NULL; if (!m_impl) { @@ -1897,7 +1921,8 @@ bool wxSocketClient::DoConnect(const wxSockAddress& remote, m_establishing = false; // Create and set up the new one - m_impl = wxSocketImpl::Create(*this); + wxSocketManager * const manager = wxSocketManager::Get(); + m_impl = manager ? manager->CreateSocket(*this) : NULL; if ( !m_impl ) return false; @@ -1979,7 +2004,8 @@ wxDatagramSocket::wxDatagramSocket( const wxSockAddress& addr, : wxSocketBase( flags, wxSOCKET_DATAGRAM ) { // Create the socket - m_impl = wxSocketImpl::Create(*this); + wxSocketManager * const manager = wxSocketManager::Get(); + m_impl = manager ? manager->CreateSocket(*this) : NULL; if (!m_impl) return; @@ -2064,4 +2090,14 @@ IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule) wxFORCE_LINK_MODULE( socketiohandler ) #endif +// same for ManagerSetter in the MSW file +#ifdef __WXMSW__ + wxFORCE_LINK_MODULE( mswsocket ) +#endif + +// and for OSXManagerSetter in the OS X one +#ifdef __WXMAC__ + wxFORCE_LINK_MODULE( osxsocket ) +#endif + #endif // wxUSE_SOCKETS