X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4017f5ca49e153e04ffd1c49bc93afd31c1cdf87..ab7049776d45e622f621dd06216a4c1a1ad34b15:/src/common/socket.cpp?ds=sidebyside diff --git a/src/common/socket.cpp b/src/common/socket.cpp index fb18c2e341..36a9dc1090 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -7,7 +7,7 @@ // (C) 1999-2000, Guillermo Rodriguez Garcia // (C) 2008 Vadim Zeitlin // RCS_ID: $Id$ -// License: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // ========================================================================== @@ -753,8 +753,11 @@ int wxSocketImpl::Write(const void *buffer, int size) namespace { -// flag indicating whether wxSocketManager was already initialized -bool gs_socketInitDone = false; +// 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 @@ -762,7 +765,7 @@ bool wxSocketBase::IsInitialized() { wxASSERT_MSG( wxIsMainThread(), "unsafe to call from other threads" ); - return gs_socketInitDone; + return gs_socketInitCount != 0; } bool wxSocketBase::Initialize() @@ -770,15 +773,15 @@ bool wxSocketBase::Initialize() wxCHECK_MSG( wxIsMainThread(), false, "must be called from the main thread" ); - if ( !gs_socketInitDone ) + if ( !gs_socketInitCount ) { wxSocketManager * const manager = wxSocketManager::Get(); if ( !manager || !manager->OnInit() ) return false; - - gs_socketInitDone = true; } + gs_socketInitCount++; + return true; } @@ -786,14 +789,15 @@ void wxSocketBase::Shutdown() { wxCHECK_RET( wxIsMainThread(), "must be called from the main thread" ); - wxCHECK_RET( gs_socketInitDone, "unnecessary call to Shutdown()" ); - - gs_socketInitDone = false; + wxCHECK_RET( gs_socketInitCount > 0, "too many calls to Shutdown()" ); - wxSocketManager * const manager = wxSocketManager::Get(); - wxCHECK_RET( manager, "should have a socket manager" ); + if ( !--gs_socketInitCount ) + { + wxSocketManager * const manager = wxSocketManager::Get(); + wxCHECK_RET( manager, "should have a socket manager" ); - manager->OnExit(); + manager->OnExit(); + } } // -------------------------------------------------------------------------- @@ -976,7 +980,11 @@ wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes) { // if we don't want to wait, just return immediately if ( m_flags & wxSOCKET_NOWAIT ) + { + // this shouldn't be counted as an error in this case + SetError(wxSOCKET_NOERROR); break; + } // otherwise wait until the socket becomes ready for reading or // an error occurs on it @@ -1105,6 +1113,9 @@ wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes) { wxSocketReadGuard read(this); + // Peek() should never block + wxSocketWaitModeChanger changeFlags(this, wxSOCKET_NOWAIT); + m_lcount = DoRead(buffer, nbytes); Pushback(buffer, m_lcount); @@ -1286,17 +1297,31 @@ wxSocketEventFlags wxSocketImpl::Select(wxSocketEventFlags flags, exceptfds; // always want to know about errors if ( flags & wxSOCKET_INPUT_FLAG ) - { preadfds = &readfds; + + if ( flags & wxSOCKET_OUTPUT_FLAG ) + pwritefds = &writefds; + + // When using non-blocking connect() the client socket becomes connected + // (successfully or not) when it becomes writable but when using + // non-blocking accept() the server socket becomes connected when it + // becomes readable. + if ( flags & wxSOCKET_CONNECTION_FLAG ) + { + if ( m_server ) + preadfds = &readfds; + else + pwritefds = &writefds; + } + + if ( preadfds ) + { wxFD_ZERO(preadfds); wxFD_SET(m_fd, preadfds); } - // when using non-blocking connect() the socket becomes connected - // (successfully or not) when it becomes writable - if ( flags & (wxSOCKET_OUTPUT_FLAG | wxSOCKET_CONNECTION_FLAG) ) + if ( pwritefds ) { - pwritefds = &writefds; wxFD_ZERO(pwritefds); wxFD_SET(m_fd, pwritefds); } @@ -1365,10 +1390,11 @@ wxSocketBase::DoWait(long timeout, wxSocketEventFlags flags) { wxCHECK_MSG( m_impl, -1, "can't wait on invalid socket" ); - // 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 ) + // we're never going to become ready in a TCP 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 and UDP client is never "connected") + if ( !m_impl->IsServer() && + m_impl->m_stream && !m_connected && !m_establishing ) return -1; // This can be set to true from Interrupt() to exit this function a.s.a.p. @@ -1782,8 +1808,7 @@ wxSocketServer::wxSocketServer(const wxSockAddress& addr, if (m_impl->CreateServer() != wxSOCKET_NOERROR) { - delete m_impl; - m_impl = NULL; + wxDELETE(m_impl); wxLogTrace( wxTRACE_Socket, wxT("*** CreateServer() failed") ); return; @@ -2023,8 +2048,7 @@ wxDatagramSocket::wxDatagramSocket( const wxSockAddress& addr, if ( m_impl->CreateUDP() != wxSOCKET_NOERROR ) { - delete m_impl; - m_impl = NULL; + wxDELETE(m_impl); return; } @@ -2092,7 +2116,7 @@ wxFORCE_LINK_MODULE( socketiohandler ) #endif // and for OSXManagerSetter in the OS X one -#ifdef __WXMAC__ +#ifdef __WXOSX__ wxFORCE_LINK_MODULE( osxsocket ) #endif