]>
git.saurik.com Git - wxWidgets.git/blob - src/unix/evtloopunix.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/unix/evtloopunix.cpp
3 // Purpose: wxEventLoop implementation
4 // Author: Lukasz Michalski (lm@zork.pl)
7 // Copyright: (c) 2006 Zork Lukasz Michalski
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ===========================================================================
13 // ===========================================================================
15 // ---------------------------------------------------------------------------
17 // ---------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
22 #if wxUSE_CONSOLE_EVENTLOOP
30 #include "wx/apptrait.h"
31 #include "wx/evtloop.h"
32 #include "wx/thread.h"
33 #include "wx/module.h"
34 #include "wx/unix/private/timer.h"
35 #include "wx/unix/private/epolldispatcher.h"
36 #include "wx/private/selectdispatcher.h"
38 #define TRACE_EVENTS _T("events")
40 // ===========================================================================
41 // wxEventLoop::PipeIOHandler implementation
42 // ===========================================================================
44 // ----------------------------------------------------------------------------
46 // ----------------------------------------------------------------------------
48 bool wxConsoleEventLoop::PipeIOHandler::Create()
50 if ( !m_pipe
.Create() )
52 wxLogError(_("Failed to create wake up pipe used by event loop."));
56 const int fdRead
= GetReadFd();
58 int flags
= fcntl(fdRead
, F_GETFL
, 0);
59 if ( flags
== -1 || fcntl(fdRead
, F_SETFL
, flags
| O_NONBLOCK
) == -1 )
61 wxLogSysError(_("Failed to switch wake up pipe to non-blocking mode"));
65 wxLogTrace(TRACE_EVENTS
, wxT("Wake up pipe (%d, %d) created"),
66 fdRead
, m_pipe
[wxPipe::Write
]);
71 // ----------------------------------------------------------------------------
73 // ----------------------------------------------------------------------------
75 void wxConsoleEventLoop::PipeIOHandler::WakeUp()
77 if ( write(m_pipe
[wxPipe::Write
], "s", 1) != 1 )
79 // don't use wxLog here, we can be in another thread and this could
80 // result in dead locks
81 perror("write(wake up pipe)");
85 void wxConsoleEventLoop::PipeIOHandler::OnReadWaiting()
87 // got wakeup from child thread: read all data available in pipe just to
88 // make it empty (evevn though we write one byte at a time from WakeUp(),
89 // it could have been called several times)
93 const int size
= read(GetReadFd(), buf
, WXSIZEOF(buf
));
95 if ( size
== 0 || (size
== -1 && errno
== EAGAIN
) )
97 // nothing left in the pipe (EAGAIN is expected for an FD with
104 wxLogSysError(_("Failed to read from wake-up pipe"));
110 wxTheApp
->ProcessPendingEvents();
113 // ===========================================================================
114 // wxEventLoop implementation
115 // ===========================================================================
117 //-----------------------------------------------------------------------------
119 //-----------------------------------------------------------------------------
121 wxConsoleEventLoop::wxConsoleEventLoop()
123 if ( !m_wakeupPipe
.Create() )
129 m_dispatcher
= wxFDIODispatcher::Get();
133 m_dispatcher
->RegisterFD
135 m_wakeupPipe
.GetReadFd(),
141 //-----------------------------------------------------------------------------
142 // events dispatch and loop handling
143 //-----------------------------------------------------------------------------
145 bool wxConsoleEventLoop::Pending() const
147 return wxTheApp
->HasPendingEvents();
150 bool wxConsoleEventLoop::Dispatch()
152 DispatchTimeout(wxFDIODispatcher::TIMEOUT_INFINITE
);
157 int wxConsoleEventLoop::DispatchTimeout(unsigned long timeout
)
160 // check if we need to decrease the timeout to account for a timer
161 wxUsecClock_t nextTimer
;
162 if ( wxTimerScheduler::Get().GetNext(&nextTimer
) )
164 unsigned long timeUntilNextTimer
= wxMilliClockToLong(nextTimer
/ 1000);
165 if ( timeUntilNextTimer
< timeout
)
166 timeout
= timeUntilNextTimer
;
168 #endif // wxUSE_TIMER
170 bool hadEvent
= m_dispatcher
->Dispatch(timeout
);
173 if ( wxTimerScheduler::Get().NotifyExpired() )
175 #endif // wxUSE_TIMER
177 wxTheApp
->ProcessPendingEvents();
179 return hadEvent
? 1 : -1;
182 void wxConsoleEventLoop::WakeUp()
184 m_wakeupPipe
.WakeUp();
187 void wxConsoleEventLoop::OnNextIteration()
189 // call the signal handlers for any signals we caught recently
190 wxTheApp
->CheckSignal();
194 wxEventLoopBase
*wxConsoleAppTraits::CreateEventLoop()
196 return new wxEventLoop();
199 #endif // wxUSE_CONSOLE_EVENTLOOP