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
This commit is contained in:
Vadim Zeitlin
2007-07-14 20:18:38 +00:00
parent 7523de907d
commit 5e1eac149f
10 changed files with 121 additions and 107 deletions

View File

@@ -45,6 +45,18 @@ class WXDLLIMPEXP_BASE wxFDIODispatcher
public: public:
enum { TIMEOUT_INFINITE = -1 }; 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 // register handler for the given descriptor with the dispatcher, return
// true on success or false on error // true on success or false on error
virtual bool RegisterFD(int fd, wxFDIOHandler *handler, int flags) = 0; virtual bool RegisterFD(int fd, wxFDIOHandler *handler, int flags) = 0;

View File

@@ -76,14 +76,8 @@ private:
class WXDLLIMPEXP_BASE wxSelectDispatcher : public wxMappedFDIODispatcher class WXDLLIMPEXP_BASE wxSelectDispatcher : public wxMappedFDIODispatcher
{ {
public: public:
// returns the unique instance of this class, the pointer shouldn't be // creates an instance of this class, the caller takes ownership of it
// deleted and is normally never NULL static wxSelectDispatcher *Create();
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();
// implement pure virtual methods of the base class // implement pure virtual methods of the base class
virtual bool RegisterFD(int fd, wxFDIOHandler *handler, int flags = wxFDIO_ALL); virtual bool RegisterFD(int fd, wxFDIOHandler *handler, int flags = wxFDIO_ALL);
@@ -92,6 +86,7 @@ public:
virtual void Dispatch(int timeout = TIMEOUT_INFINITE); virtual void Dispatch(int timeout = TIMEOUT_INFINITE);
protected: protected:
// ctor is not public, use Create()
wxSelectDispatcher(); wxSelectDispatcher();
private: private:

View File

@@ -15,6 +15,8 @@
#include "wx/setup.h" #include "wx/setup.h"
#endif #endif
class wxGSocketIOHandler;
#if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
#ifndef __GSOCKET_STANDALONE__ #ifndef __GSOCKET_STANDALONE__
@@ -23,7 +25,7 @@
#include "gsocket.h" #include "gsocket.h"
#endif #endif
class GSocketGUIFunctionsTableConcrete: public GSocketGUIFunctionsTable class GSocketGUIFunctionsTableConcrete : public GSocketGUIFunctionsTable
{ {
public: public:
virtual bool OnInit(); virtual bool OnInit();
@@ -84,6 +86,7 @@ public:
/* DFE: We can't protect these data member until the GUI code is updated */ /* DFE: We can't protect these data member until the GUI code is updated */
/* protected: */ /* protected: */
int m_fd; int m_fd;
wxGSocketIOHandler *m_handler;
GAddress *m_local; GAddress *m_local;
GAddress *m_peer; GAddress *m_peer;
GSocketError m_error; GSocketError m_error;

View File

@@ -20,11 +20,11 @@
class WXDLLIMPEXP_CORE wxEpollDispatcher : public wxFDIODispatcher class WXDLLIMPEXP_CORE wxEpollDispatcher : public wxFDIODispatcher
{ {
public: 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 // epoll() is not supported on this system
// //
// do not delete the returned pointer // the caller should delete the returned pointer
static wxEpollDispatcher *Get(); static wxEpollDispatcher *Create();
// implement base class pure virtual methods // implement base class pure virtual methods
virtual bool RegisterFD(int fd, wxFDIOHandler* handler, int flags = wxFDIO_ALL); virtual bool RegisterFD(int fd, wxFDIOHandler* handler, int flags = wxFDIO_ALL);
@@ -33,11 +33,8 @@ public:
virtual void Dispatch(int timeout = TIMEOUT_INFINITE); virtual void Dispatch(int timeout = TIMEOUT_INFINITE);
private: private:
// ctor is private, use Get() // ctor is private, use Create()
wxEpollDispatcher(); wxEpollDispatcher(int epollDescriptor);
// return true if the object was successfully initialized
bool IsOk() const { return m_epollDescriptor != -1; }
int m_epollDescriptor; int m_epollDescriptor;
}; };

View File

@@ -24,14 +24,56 @@
#endif #endif
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/module.h"
#endif //WX_PRECOMP #endif //WX_PRECOMP
#include "wx/private/fdiodispatcher.h" #include "wx/private/fdiodispatcher.h"
#include "wx/private/selectdispatcher.h"
#ifdef __UNIX__
#include "wx/unix/private/epolldispatcher.h"
#endif
wxFDIODispatcher *gs_dispatcher = NULL;
// ============================================================================ // ============================================================================
// implementation // 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 wxFDIOHandler *wxMappedFDIODispatcher::FindHandler(int fd) const
{ {
const wxFDIOHandlerMap::const_iterator it = m_handlers.find(fd); const wxFDIOHandlerMap::const_iterator it = m_handlers.find(fd);
@@ -89,3 +131,18 @@ bool wxMappedFDIODispatcher::UnregisterFD(int fd)
return true; 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)

View File

@@ -127,14 +127,21 @@ void GSocketGUIFunctionsTableConcrete::Install_Callback(GSocket *socket,
default: return; default: return;
} }
wxSelectDispatcher * const dispatcher = wxSelectDispatcher::Get(); wxFDIODispatcher * const dispatcher = wxFDIODispatcher::Get();
if ( !dispatcher ) if ( !dispatcher )
return; return;
wxGSocketIOHandler * wxGSocketIOHandler *& handler = socket->m_handler;
handler = (wxGSocketIOHandler*)dispatcher->FindHandler(fd);
if ( !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); handler = new wxGSocketIOHandler(socket);
} }
@@ -149,7 +156,10 @@ void GSocketGUIFunctionsTableConcrete::Install_Callback(GSocket *socket,
handler->AddFlag(wxFDIO_OUTPUT); 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, 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; const wxFDIODispatcherEntryFlags flag = c == 0 ? wxFDIO_INPUT : wxFDIO_OUTPUT;
wxSelectDispatcher * const dispatcher = wxSelectDispatcher::Get(); wxFDIODispatcher * const dispatcher = wxFDIODispatcher::Get();
if ( !dispatcher ) if ( !dispatcher )
return; return;
wxGSocketIOHandler * const wxGSocketIOHandler *& handler = socket->m_handler;
handler = wx_static_cast(wxGSocketIOHandler *, dispatcher->FindHandler(fd));
if ( handler ) if ( handler )
{ {
handler->RemoveFlag(flag); handler->RemoveFlag(flag);

View File

@@ -22,7 +22,6 @@
#if wxUSE_SELECT_DISPATCHER #if wxUSE_SELECT_DISPATCHER
#include "wx/private/selectdispatcher.h" #include "wx/private/selectdispatcher.h"
#include "wx/module.h"
#include "wx/unix/private.h" #include "wx/unix/private.h"
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
@@ -132,26 +131,10 @@ void wxSelectSets::Handle(int fd, wxFDIOHandler& handler) const
// wxSelectDispatcher // wxSelectDispatcher
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
static wxSelectDispatcher *gs_selectDispatcher = NULL;
/* static */ /* static */
wxSelectDispatcher *wxSelectDispatcher::Get() wxSelectDispatcher *wxSelectDispatcher::Create()
{ {
if ( !gs_selectDispatcher ) return new wxSelectDispatcher;
{
// 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);
} }
wxSelectDispatcher::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 #endif // wxUSE_SELECT_DISPATCHER

View File

@@ -23,7 +23,6 @@
#include "wx/unix/private/epolldispatcher.h" #include "wx/unix/private/epolldispatcher.h"
#include "wx/unix/private.h" #include "wx/unix/private.h"
#include "wx/module.h"
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/log.h" #include "wx/log.h"
@@ -35,8 +34,6 @@
#define wxEpollDispatcher_Trace wxT("epolldispatcher") #define wxEpollDispatcher_Trace wxT("epolldispatcher")
static wxEpollDispatcher *gs_epollDispatcher = NULL;
// ============================================================================ // ============================================================================
// implementation // implementation
// ============================================================================ // ============================================================================
@@ -75,13 +72,24 @@ static uint32_t GetEpollMask(int flags, int fd)
// wxEpollDispatcher // wxEpollDispatcher
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
wxEpollDispatcher::wxEpollDispatcher() /* static */
wxEpollDispatcher *wxEpollDispatcher::Create()
{ {
m_epollDescriptor = epoll_create(1024); int epollDescriptor = epoll_create(1024);
if ( m_epollDescriptor == -1 ) if ( epollDescriptor == -1 )
{ {
wxLogSysError(_("Failed to create epoll descriptor")); 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) 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 #endif // wxUSE_EPOLL_DISPATCHER

View File

@@ -125,15 +125,9 @@ wxConsoleEventLoop::wxConsoleEventLoop()
return; return;
} }
#ifdef wxUSE_EPOLL_DISPATCHER m_dispatcher = wxFDIODispatcher::Get();
m_dispatcher = wxEpollDispatcher::Get();
if ( !m_dispatcher ) if ( !m_dispatcher )
#endif // wxUSE_EPOLL_DISPATCHER return;
#if wxUSE_SELECT_DISPATCHER
m_dispatcher = wxSelectDispatcher::Get();
#endif // wxUSE_WCHAR_T
wxCHECK_RET( m_dispatcher, _T("failed to create IO dispatcher") );
m_dispatcher->RegisterFD m_dispatcher->RegisterFD
( (

View File

@@ -20,6 +20,7 @@
#ifndef __GSOCKET_STANDALONE__ #ifndef __GSOCKET_STANDALONE__
#include "wx/defs.h" #include "wx/defs.h"
#include "wx/private/gsocketiohandler.h"
#endif #endif
#if defined(__VISAGECPP__) #if defined(__VISAGECPP__)
@@ -520,6 +521,8 @@ GSocket::GSocket()
int i; int i;
m_fd = INVALID_SOCKET; m_fd = INVALID_SOCKET;
m_handler = NULL;
for (i=0;i<GSOCK_MAX_EVENT;i++) for (i=0;i<GSOCK_MAX_EVENT;i++)
{ {
m_cbacks[i] = NULL; m_cbacks[i] = NULL;
@@ -565,6 +568,8 @@ GSocket::~GSocket()
/* Per-socket GUI-specific cleanup */ /* Per-socket GUI-specific cleanup */
gs_gui_functions->Destroy_Socket(this); gs_gui_functions->Destroy_Socket(this);
delete m_handler;
/* Destroy private addresses */ /* Destroy private addresses */
if (m_local) if (m_local)
GAddress_destroy(m_local); GAddress_destroy(m_local);