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:
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;

View File

@ -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:

View File

@ -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;

View File

@ -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;
};

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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
(

View File

@ -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;i<GSOCK_MAX_EVENT;i++)
{
m_cbacks[i] = NULL;
@ -565,6 +568,8 @@ GSocket::~GSocket()
/* Per-socket GUI-specific cleanup */
gs_gui_functions->Destroy_Socket(this);
delete m_handler;
/* Destroy private addresses */
if (m_local)
GAddress_destroy(m_local);