X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2f10f4238afa739b528d4115a5f2e8a0e87f2bcb..5541d1fda4b73af86e42b2f43724f0c063a352d0:/src/common/socket.cpp diff --git a/src/common/socket.cpp b/src/common/socket.cpp index c5b1bab4e4..95669073cd 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -110,6 +110,44 @@ public: // wxSocketBase // ========================================================================== +// -------------------------------------------------------------------------- +// 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; + +bool wxSocketBase::IsInitialized() +{ + return m_countInit > 0; +} + +bool wxSocketBase::Initialize() +{ + if ( !m_countInit++ ) + { + if ( !GSocket_Init() ) + { + m_countInit--; + + return FALSE; + } + } + + return TRUE; +} + +void wxSocketBase::Shutdown() +{ + // we should be initialized + wxASSERT_MSG( m_countInit, _T("extra call to Shutdown()") ); + if ( !--m_countInit ) + { + GSocket_Cleanup(); + } +} + // -------------------------------------------------------------------------- // Ctor and dtor // -------------------------------------------------------------------------- @@ -145,6 +183,13 @@ void wxSocketBase::Init() m_cbk = NULL; m_cdata = NULL; #endif // WXWIN_COMPATIBILITY + + if ( !IsInitialized() ) + { + // this Initialize() will be undone by wxSocketModule::OnExit(), all the + // other calls to it should be matched by a call to Shutdown() + Initialize(); + } } wxSocketBase::wxSocketBase() @@ -481,7 +526,7 @@ wxUint32 wxSocketBase::_Write(const void *buffer, wxUint32 nbytes) { bool more = TRUE; - while (more) + while (more) { if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForWrite() ) break; @@ -862,9 +907,10 @@ char *wxSocketBase::CallbackData(char *data) // decoupled from wx_socket_callback and thus they suffer from a variety // of problems. Avoid them where possible and use events instead. -static void LINKAGEMODE wx_socket_callback(GSocket * WXUNUSED(socket), - GSocketEvent notification, - char *cdata) +extern "C" +void LINKAGEMODE wx_socket_callback(GSocket * WXUNUSED(socket), + GSocketEvent notification, + char *cdata) { wxSocketBase *sckobj = (wxSocketBase *)cdata; @@ -1010,7 +1056,7 @@ wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek) // ========================================================================== -// wxSocketServer +// wxSocketServer // ========================================================================== // -------------------------------------------------------------------------- @@ -1088,7 +1134,10 @@ wxSocketBase *wxSocketServer::Accept(bool wait) sock->SetFlags(m_flags); if (!AcceptWith(*sock, wait)) - return NULL; + { + sock->Destroy(); + sock = NULL; + } return sock; } @@ -1232,36 +1281,27 @@ wxDatagramSocket& wxDatagramSocket::SendTo( wxSockAddress& addr, return (*this); } -// ========================================================================== -// wxSocketEvent -// ========================================================================== - -wxSocketEvent::wxSocketEvent(int id) : wxEvent(id) -{ - SetEventType( (wxEventType)wxEVT_SOCKET ); -} - -void wxSocketEvent::CopyObject(wxObject& object_dest) const -{ - wxSocketEvent *event = (wxSocketEvent *)&object_dest; - - wxEvent::CopyObject(object_dest); - - event->m_event = m_event; - event->m_clientData = m_clientData; -} - // ========================================================================== // wxSocketModule // ========================================================================== class WXDLLEXPORT wxSocketModule : public wxModule { - DECLARE_DYNAMIC_CLASS(wxSocketModule) - public: - bool OnInit() { return GSocket_Init() != 0; } - void OnExit() { GSocket_Cleanup(); } + virtual bool OnInit() + { + // wxSocketBase will call GSocket_Init() itself when/if needed + return TRUE; + } + + virtual void OnExit() + { + if ( wxSocketBase::IsInitialized() ) + wxSocketBase::Shutdown(); + } + +private: + DECLARE_DYNAMIC_CLASS(wxSocketModule) }; IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)