Files
wxWidgets/src/unix/evtloopunix.cpp
Stefan Neis 37ab9399a8 Moved wxConsoleAppTraits::CreateEventLoop from baseunix.cpp to evtloopunix.cpp,
so Unix' wxConsoleEventLoop can also be shared by platforms not having
        the complete ConsoleAppTraits of Unix (e.g. OS/2).


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@50133 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2007-11-21 14:12:16 +00:00

196 lines
5.3 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: src/unix/evtloopunix.cpp
// Purpose: wxEventLoop implementation
// Author: Lukasz Michalski (lm@zork.pl)
// Created: 2007-05-07
// RCS-ID: $Id$
// Copyright: (c) 2006 Zork Lukasz Michalski
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ===========================================================================
// declarations
// ===========================================================================
// ---------------------------------------------------------------------------
// headers
// ---------------------------------------------------------------------------
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#if wxUSE_CONSOLE_EVENTLOOP
#ifndef WX_PRECOMP
#include "wx/app.h"
#include "wx/log.h"
#endif
#include <errno.h>
#include "wx/apptrait.h"
#include "wx/evtloop.h"
#include "wx/thread.h"
#include "wx/module.h"
#include "wx/unix/private/timer.h"
#include "wx/unix/private/epolldispatcher.h"
#include "wx/private/selectdispatcher.h"
#define TRACE_EVENTS _T("events")
// ===========================================================================
// wxEventLoop::PipeIOHandler implementation
// ===========================================================================
// ----------------------------------------------------------------------------
// initialization
// ----------------------------------------------------------------------------
bool wxConsoleEventLoop::PipeIOHandler::Create()
{
if ( !m_pipe.Create() )
{
wxLogError(_("Failed to create wake up pipe used by event loop."));
return false;
}
const int fdRead = GetReadFd();
int flags = fcntl(fdRead, F_GETFL, 0);
if ( flags == -1 || fcntl(fdRead, F_SETFL, flags | O_NONBLOCK) == -1 )
{
wxLogSysError(_("Failed to switch wake up pipe to non-blocking mode"));
return false;
}
wxLogTrace(TRACE_EVENTS, wxT("Wake up pipe (%d, %d) created"),
fdRead, m_pipe[wxPipe::Write]);
return true;
}
// ----------------------------------------------------------------------------
// wakeup handling
// ----------------------------------------------------------------------------
void wxConsoleEventLoop::PipeIOHandler::WakeUp()
{
if ( write(m_pipe[wxPipe::Write], "s", 1) != 1 )
{
// don't use wxLog here, we can be in another thread and this could
// result in dead locks
perror("write(wake up pipe)");
}
}
void wxConsoleEventLoop::PipeIOHandler::OnReadWaiting()
{
// got wakeup from child thread: read all data available in pipe just to
// make it empty (evevn though we write one byte at a time from WakeUp(),
// it could have been called several times)
char buf[4];
for ( ;; )
{
const int size = read(GetReadFd(), buf, WXSIZEOF(buf));
if ( size == 0 || (size == -1 && errno == EAGAIN) )
{
// nothing left in the pipe (EAGAIN is expected for an FD with
// O_NONBLOCK)
break;
}
if ( size == -1 )
{
wxLogSysError(_("Failed to read from wake-up pipe"));
break;
}
}
wxTheApp->ProcessPendingEvents();
}
// ===========================================================================
// wxEventLoop implementation
// ===========================================================================
//-----------------------------------------------------------------------------
// initialization
//-----------------------------------------------------------------------------
wxConsoleEventLoop::wxConsoleEventLoop()
{
if ( !m_wakeupPipe.Create() )
{
m_dispatcher = NULL;
return;
}
m_dispatcher = wxFDIODispatcher::Get();
if ( !m_dispatcher )
return;
m_dispatcher->RegisterFD
(
m_wakeupPipe.GetReadFd(),
&m_wakeupPipe,
wxFDIO_INPUT
);
}
//-----------------------------------------------------------------------------
// events dispatch and loop handling
//-----------------------------------------------------------------------------
bool wxConsoleEventLoop::Pending() const
{
return wxTheApp->HasPendingEvents();
}
bool wxConsoleEventLoop::Dispatch()
{
wxTheApp->ProcessPendingEvents();
return true;
}
void wxConsoleEventLoop::WakeUp()
{
m_wakeupPipe.WakeUp();
}
void wxConsoleEventLoop::OnNextIteration()
{
// calculate the timeout until the next timer expiration
int timeout;
#if wxUSE_TIMER
wxUsecClock_t nextTimer;
if ( wxTimerScheduler::Get().GetNext(&nextTimer) )
{
// timeout is in ms
timeout = (nextTimer / 1000).ToLong();
}
else // no timers, we can block forever
#endif // wxUSE_TIMER
{
timeout = wxFDIODispatcher::TIMEOUT_INFINITE;
}
m_dispatcher->Dispatch(timeout);
#if wxUSE_TIMER
wxTimerScheduler::Get().NotifyExpired();
#endif
// call the signal handlers for any signals we caught recently
wxTheApp->CheckSignal();
}
wxEventLoopBase *wxConsoleAppTraits::CreateEventLoop()
{
return new wxEventLoop();
}
#endif // wxUSE_CONSOLE_EVENTLOOP