From 5e1eac149fc18f51d5a25ac00d957ccaad87b3fa Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 14 Jul 2007 20:18:38 +0000 Subject: [PATCH] create the single global IO dispatcher in wxFDIODispatcher; don't use wxSelectDispatcher in wxGSocket as the global dispatcher may be of a different type (modified patch 1733626) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@47471 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/private/fdiodispatcher.h | 12 +++++ include/wx/private/selectdispatcher.h | 11 ++--- include/wx/unix/gsockunx.h | 5 +- include/wx/unix/private/epolldispatcher.h | 13 ++---- src/common/fdiodispatcher.cpp | 57 +++++++++++++++++++++++ src/common/gsocketiohandler.cpp | 25 ++++++---- src/common/selectdispatcher.cpp | 37 +-------------- src/unix/epolldispatcher.cpp | 53 ++++++--------------- src/unix/evtloopunix.cpp | 10 +--- src/unix/gsocket.cpp | 5 ++ 10 files changed, 121 insertions(+), 107 deletions(-) diff --git a/include/wx/private/fdiodispatcher.h b/include/wx/private/fdiodispatcher.h index 52e8efba7b..04128f858b 100644 --- a/include/wx/private/fdiodispatcher.h +++ b/include/wx/private/fdiodispatcher.h @@ -45,6 +45,18 @@ class WXDLLIMPEXP_BASE wxFDIODispatcher public: enum { TIMEOUT_INFINITE = -1 }; + // return the global dispatcher to be used for IO events, can be NULL only + // if wxSelectDispatcher wasn't compiled into the library at all as + // creating it never fails + // + // don't delete the returned pointer + static wxFDIODispatcher *Get(); + + // if we have any registered handlers, check for any pending events to them + // and dispatch them -- this is used from wxX11 and wxDFB event loops + // implementation + static void DispatchPending(); + // register handler for the given descriptor with the dispatcher, return // true on success or false on error virtual bool RegisterFD(int fd, wxFDIOHandler *handler, int flags) = 0; diff --git a/include/wx/private/selectdispatcher.h b/include/wx/private/selectdispatcher.h index d61f0daf77..eea139f37c 100644 --- a/include/wx/private/selectdispatcher.h +++ b/include/wx/private/selectdispatcher.h @@ -76,14 +76,8 @@ private: class WXDLLIMPEXP_BASE wxSelectDispatcher : public wxMappedFDIODispatcher { public: - // returns the unique instance of this class, the pointer shouldn't be - // deleted and is normally never NULL - static wxSelectDispatcher *Get(); - - // if we have any registered handlers, check for any pending events to them - // and dispatch them -- this is used from wxX11 and wxDFB event loops - // implementation - static void DispatchPending(); + // creates an instance of this class, the caller takes ownership of it + static wxSelectDispatcher *Create(); // implement pure virtual methods of the base class virtual bool RegisterFD(int fd, wxFDIOHandler *handler, int flags = wxFDIO_ALL); @@ -92,6 +86,7 @@ public: virtual void Dispatch(int timeout = TIMEOUT_INFINITE); protected: + // ctor is not public, use Create() wxSelectDispatcher(); private: diff --git a/include/wx/unix/gsockunx.h b/include/wx/unix/gsockunx.h index 438b725520..a01f6013d2 100644 --- a/include/wx/unix/gsockunx.h +++ b/include/wx/unix/gsockunx.h @@ -15,6 +15,8 @@ #include "wx/setup.h" #endif +class wxGSocketIOHandler; + #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) #ifndef __GSOCKET_STANDALONE__ @@ -23,7 +25,7 @@ #include "gsocket.h" #endif -class GSocketGUIFunctionsTableConcrete: public GSocketGUIFunctionsTable +class GSocketGUIFunctionsTableConcrete : public GSocketGUIFunctionsTable { public: virtual bool OnInit(); @@ -84,6 +86,7 @@ public: /* DFE: We can't protect these data member until the GUI code is updated */ /* protected: */ int m_fd; + wxGSocketIOHandler *m_handler; GAddress *m_local; GAddress *m_peer; GSocketError m_error; diff --git a/include/wx/unix/private/epolldispatcher.h b/include/wx/unix/private/epolldispatcher.h index c42b40f0a4..f76cf6e8d7 100644 --- a/include/wx/unix/private/epolldispatcher.h +++ b/include/wx/unix/private/epolldispatcher.h @@ -20,11 +20,11 @@ class WXDLLIMPEXP_CORE wxEpollDispatcher : public wxFDIODispatcher { public: - // get pointer to the unique instance of this class, can return NULL if + // create a new instance of this class, can return NULL if // epoll() is not supported on this system // - // do not delete the returned pointer - static wxEpollDispatcher *Get(); + // the caller should delete the returned pointer + static wxEpollDispatcher *Create(); // implement base class pure virtual methods virtual bool RegisterFD(int fd, wxFDIOHandler* handler, int flags = wxFDIO_ALL); @@ -33,11 +33,8 @@ public: virtual void Dispatch(int timeout = TIMEOUT_INFINITE); private: - // ctor is private, use Get() - wxEpollDispatcher(); - - // return true if the object was successfully initialized - bool IsOk() const { return m_epollDescriptor != -1; } + // ctor is private, use Create() + wxEpollDispatcher(int epollDescriptor); int m_epollDescriptor; }; diff --git a/src/common/fdiodispatcher.cpp b/src/common/fdiodispatcher.cpp index 112f892dc2..f6a131dc01 100644 --- a/src/common/fdiodispatcher.cpp +++ b/src/common/fdiodispatcher.cpp @@ -24,14 +24,56 @@ #endif #ifndef WX_PRECOMP + #include "wx/module.h" #endif //WX_PRECOMP #include "wx/private/fdiodispatcher.h" +#include "wx/private/selectdispatcher.h" +#ifdef __UNIX__ + #include "wx/unix/private/epolldispatcher.h" +#endif + +wxFDIODispatcher *gs_dispatcher = NULL; + // ============================================================================ // implementation // ============================================================================ +// ---------------------------------------------------------------------------- +// wxFDIODispatcher +// ---------------------------------------------------------------------------- + +/* static */ +wxFDIODispatcher *wxFDIODispatcher::Get() +{ + if ( !gs_dispatcher ) + { +#ifdef wxUSE_EPOLL_DISPATCHER + gs_dispatcher = wxEpollDispatcher::Create(); + if ( !gs_dispatcher ) +#endif // wxUSE_EPOLL_DISPATCHER +#if wxUSE_SELECT_DISPATCHER + gs_dispatcher = wxSelectDispatcher::Create(); +#endif // wxUSE_WCHAR_T + } + + wxASSERT_MSG( gs_dispatcher, _T("failed to create any IO dispatchers") ); + + return gs_dispatcher; +} + +/* static */ +void wxFDIODispatcher::DispatchPending() +{ + if ( gs_dispatcher ) + gs_dispatcher->Dispatch(0); +} + +// ---------------------------------------------------------------------------- +// wxMappedFDIODispatcher +// ---------------------------------------------------------------------------- + wxFDIOHandler *wxMappedFDIODispatcher::FindHandler(int fd) const { const wxFDIOHandlerMap::const_iterator it = m_handlers.find(fd); @@ -89,3 +131,18 @@ bool wxMappedFDIODispatcher::UnregisterFD(int fd) return true; } +// ---------------------------------------------------------------------------- +// wxSelectDispatcherModule +// ---------------------------------------------------------------------------- + +class wxFDIODispatcherModule : public wxModule +{ +public: + virtual bool OnInit() { return true; } + virtual void OnExit() { wxDELETE(gs_dispatcher); } + +private: + DECLARE_DYNAMIC_CLASS(wxFDIODispatcherModule) +}; + +IMPLEMENT_DYNAMIC_CLASS(wxFDIODispatcherModule, wxModule) diff --git a/src/common/gsocketiohandler.cpp b/src/common/gsocketiohandler.cpp index a5ae3e476d..ece535c02c 100644 --- a/src/common/gsocketiohandler.cpp +++ b/src/common/gsocketiohandler.cpp @@ -127,14 +127,21 @@ void GSocketGUIFunctionsTableConcrete::Install_Callback(GSocket *socket, default: return; } - wxSelectDispatcher * const dispatcher = wxSelectDispatcher::Get(); + wxFDIODispatcher * const dispatcher = wxFDIODispatcher::Get(); if ( !dispatcher ) return; - wxGSocketIOHandler * - handler = (wxGSocketIOHandler*)dispatcher->FindHandler(fd); - if ( !handler ) + wxGSocketIOHandler *& handler = socket->m_handler; + + // we should register the new handlers but modify the existing ones in place + bool registerHandler; + if ( handler ) { + registerHandler = false; + } + else // no existing handler + { + registerHandler = true; handler = new wxGSocketIOHandler(socket); } @@ -149,7 +156,10 @@ void GSocketGUIFunctionsTableConcrete::Install_Callback(GSocket *socket, handler->AddFlag(wxFDIO_OUTPUT); } - dispatcher->RegisterFD(fd, handler, handler->GetFlags()); + if ( registerHandler ) + dispatcher->RegisterFD(fd, handler, handler->GetFlags()); + else + dispatcher->ModifyFD(fd, handler, handler->GetFlags()); } void GSocketGUIFunctionsTableConcrete::Uninstall_Callback(GSocket *socket, @@ -175,12 +185,11 @@ void GSocketGUIFunctionsTableConcrete::Uninstall_Callback(GSocket *socket, const wxFDIODispatcherEntryFlags flag = c == 0 ? wxFDIO_INPUT : wxFDIO_OUTPUT; - wxSelectDispatcher * const dispatcher = wxSelectDispatcher::Get(); + wxFDIODispatcher * const dispatcher = wxFDIODispatcher::Get(); if ( !dispatcher ) return; - wxGSocketIOHandler * const - handler = wx_static_cast(wxGSocketIOHandler *, dispatcher->FindHandler(fd)); + wxGSocketIOHandler *& handler = socket->m_handler; if ( handler ) { handler->RemoveFlag(flag); diff --git a/src/common/selectdispatcher.cpp b/src/common/selectdispatcher.cpp index 654eee9f4a..f13df0daa6 100644 --- a/src/common/selectdispatcher.cpp +++ b/src/common/selectdispatcher.cpp @@ -22,7 +22,6 @@ #if wxUSE_SELECT_DISPATCHER #include "wx/private/selectdispatcher.h" -#include "wx/module.h" #include "wx/unix/private.h" #ifndef WX_PRECOMP @@ -132,26 +131,10 @@ void wxSelectSets::Handle(int fd, wxFDIOHandler& handler) const // wxSelectDispatcher // ---------------------------------------------------------------------------- -static wxSelectDispatcher *gs_selectDispatcher = NULL; - /* static */ -wxSelectDispatcher *wxSelectDispatcher::Get() +wxSelectDispatcher *wxSelectDispatcher::Create() { - if ( !gs_selectDispatcher ) - { - // the dispatcher should be only created from one thread so it should - // be ok to use a global without any protection here - gs_selectDispatcher = new wxSelectDispatcher; - } - - return gs_selectDispatcher; -} - -/* static */ -void wxSelectDispatcher::DispatchPending() -{ - if ( gs_selectDispatcher ) - gs_selectDispatcher->Dispatch(0); + return new wxSelectDispatcher; } wxSelectDispatcher::wxSelectDispatcher() @@ -264,20 +247,4 @@ void wxSelectDispatcher::Dispatch(int timeout) } } -// ---------------------------------------------------------------------------- -// wxSelectDispatcherModule -// ---------------------------------------------------------------------------- - -class wxSelectDispatcherModule : public wxModule -{ -public: - virtual bool OnInit() { return true; } - virtual void OnExit() { wxDELETE(gs_selectDispatcher); } - -private: - DECLARE_DYNAMIC_CLASS(wxSelectDispatcherModule) -}; - -IMPLEMENT_DYNAMIC_CLASS(wxSelectDispatcherModule, wxModule) - #endif // wxUSE_SELECT_DISPATCHER diff --git a/src/unix/epolldispatcher.cpp b/src/unix/epolldispatcher.cpp index 16ec914ad6..a8cb94910c 100644 --- a/src/unix/epolldispatcher.cpp +++ b/src/unix/epolldispatcher.cpp @@ -23,7 +23,6 @@ #include "wx/unix/private/epolldispatcher.h" #include "wx/unix/private.h" -#include "wx/module.h" #ifndef WX_PRECOMP #include "wx/log.h" @@ -35,8 +34,6 @@ #define wxEpollDispatcher_Trace wxT("epolldispatcher") -static wxEpollDispatcher *gs_epollDispatcher = NULL; - // ============================================================================ // implementation // ============================================================================ @@ -75,13 +72,24 @@ static uint32_t GetEpollMask(int flags, int fd) // wxEpollDispatcher // ---------------------------------------------------------------------------- -wxEpollDispatcher::wxEpollDispatcher() +/* static */ +wxEpollDispatcher *wxEpollDispatcher::Create() { - m_epollDescriptor = epoll_create(1024); - if ( m_epollDescriptor == -1 ) + int epollDescriptor = epoll_create(1024); + if ( epollDescriptor == -1 ) { wxLogSysError(_("Failed to create epoll descriptor")); + return NULL; } + + return new wxEpollDispatcher(epollDescriptor); +} + +wxEpollDispatcher::wxEpollDispatcher(int epollDescriptor) +{ + wxASSERT_MSG( epollDescriptor != -1, _T("invalid descriptor") ); + + m_epollDescriptor = epollDescriptor; } bool wxEpollDispatcher::RegisterFD(int fd, wxFDIOHandler* handler, int flags) @@ -175,37 +183,4 @@ void wxEpollDispatcher::Dispatch(int timeout) } } -/* static */ -wxEpollDispatcher *wxEpollDispatcher::Get() -{ - if ( !gs_epollDispatcher ) - { - gs_epollDispatcher = new wxEpollDispatcher; - if ( !gs_epollDispatcher->IsOk() ) - { - delete gs_epollDispatcher; - gs_epollDispatcher = NULL; - } - } - - return gs_epollDispatcher; -} - -// ---------------------------------------------------------------------------- -// wxEpollDispatcherModule -// ---------------------------------------------------------------------------- - -class wxEpollDispatcherModule : public wxModule -{ -public: - wxEpollDispatcherModule() { } - - virtual bool OnInit() { return true; } - virtual void OnExit() { wxDELETE(gs_epollDispatcher); } - - DECLARE_DYNAMIC_CLASS(wxEpollDispatcherModule) -}; - -IMPLEMENT_DYNAMIC_CLASS(wxEpollDispatcherModule, wxModule) - #endif // wxUSE_EPOLL_DISPATCHER diff --git a/src/unix/evtloopunix.cpp b/src/unix/evtloopunix.cpp index 39afb42db0..c147a7651d 100644 --- a/src/unix/evtloopunix.cpp +++ b/src/unix/evtloopunix.cpp @@ -125,15 +125,9 @@ wxConsoleEventLoop::wxConsoleEventLoop() return; } -#ifdef wxUSE_EPOLL_DISPATCHER - m_dispatcher = wxEpollDispatcher::Get(); + m_dispatcher = wxFDIODispatcher::Get(); if ( !m_dispatcher ) -#endif // wxUSE_EPOLL_DISPATCHER -#if wxUSE_SELECT_DISPATCHER - m_dispatcher = wxSelectDispatcher::Get(); -#endif // wxUSE_WCHAR_T - - wxCHECK_RET( m_dispatcher, _T("failed to create IO dispatcher") ); + return; m_dispatcher->RegisterFD ( diff --git a/src/unix/gsocket.cpp b/src/unix/gsocket.cpp index 13a3b5b12c..0c8f5f9a40 100644 --- a/src/unix/gsocket.cpp +++ b/src/unix/gsocket.cpp @@ -20,6 +20,7 @@ #ifndef __GSOCKET_STANDALONE__ #include "wx/defs.h" +#include "wx/private/gsocketiohandler.h" #endif #if defined(__VISAGECPP__) @@ -520,6 +521,8 @@ GSocket::GSocket() int i; m_fd = INVALID_SOCKET; + m_handler = NULL; + for (i=0;iDestroy_Socket(this); + delete m_handler; + /* Destroy private addresses */ if (m_local) GAddress_destroy(m_local);