]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/unix/evtloopunix.cpp
Treat G_IO_HUP as read, not error, event because EOF is not exceptional.
[wxWidgets.git] / src / unix / evtloopunix.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/unix/evtloopunix.cpp
3// Purpose: wxEventLoop implementation
4// Author: Lukasz Michalski (lm@zork.pl)
5// Created: 2007-05-07
6// RCS-ID: $Id$
7// Copyright: (c) 2006 Zork Lukasz Michalski
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// ===========================================================================
12// declarations
13// ===========================================================================
14
15// ---------------------------------------------------------------------------
16// headers
17// ---------------------------------------------------------------------------
18
19// For compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#if wxUSE_CONSOLE_EVENTLOOP
23
24#include "wx/evtloop.h"
25
26#ifndef WX_PRECOMP
27 #include "wx/app.h"
28 #include "wx/log.h"
29#endif
30
31#include "wx/apptrait.h"
32#include "wx/scopedptr.h"
33#include "wx/thread.h"
34#include "wx/module.h"
35#include "wx/unix/private/timer.h"
36#include "wx/unix/private/epolldispatcher.h"
37#include "wx/unix/private/wakeuppipe.h"
38#include "wx/private/selectdispatcher.h"
39#include "wx/private/eventloopsourcesmanager.h"
40#include "wx/private/fdioeventloopsourcehandler.h"
41#include "wx/private/eventloopsourcesmanager.h"
42
43#if wxUSE_EVENTLOOP_SOURCE
44 #include "wx/evtloopsrc.h"
45#endif // wxUSE_EVENTLOOP_SOURCE
46
47// ===========================================================================
48// wxEventLoop implementation
49// ===========================================================================
50
51//-----------------------------------------------------------------------------
52// initialization
53//-----------------------------------------------------------------------------
54
55wxConsoleEventLoop::wxConsoleEventLoop()
56{
57 // Be pessimistic initially and assume that we failed to initialize.
58 m_dispatcher = NULL;
59 m_wakeupPipe = NULL;
60 m_wakeupSource = NULL;
61
62 // Create the pipe.
63 wxScopedPtr<wxWakeUpPipeMT> wakeupPipe(new wxWakeUpPipeMT);
64 const int pipeFD = wakeupPipe->GetReadFd();
65 if ( pipeFD == wxPipe::INVALID_FD )
66 return;
67
68 // And start monitoring it in our event loop.
69 m_wakeupSource = wxEventLoopBase::AddSourceForFD
70 (
71 pipeFD,
72 wakeupPipe.get(),
73 wxFDIO_INPUT
74 );
75
76 if ( !m_wakeupSource )
77 return;
78
79 // This is a bit ugly but we know that AddSourceForFD() used the currently
80 // active dispatcher to register this source, so use the same one for our
81 // other operations. Of course, currently the dispatcher returned by
82 // wxFDIODispatcher::Get() is always the same one anyhow so it doesn't
83 // really matter, but if we started returning different things later, it
84 // would.
85 m_dispatcher = wxFDIODispatcher::Get();
86
87 m_wakeupPipe = wakeupPipe.release();
88}
89
90wxConsoleEventLoop::~wxConsoleEventLoop()
91{
92 if ( m_wakeupPipe )
93 {
94 delete m_wakeupSource;
95
96 delete m_wakeupPipe;
97 }
98}
99
100//-----------------------------------------------------------------------------
101// adding & removing sources
102//-----------------------------------------------------------------------------
103
104#if wxUSE_EVENTLOOP_SOURCE
105
106class wxConsoleEventLoopSourcesManager : public wxEventLoopSourcesManagerBase
107{
108public:
109 wxEventLoopSource* AddSourceForFD( int fd,
110 wxEventLoopSourceHandler *handler,
111 int flags)
112 {
113 wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" );
114
115 wxLogTrace(wxTRACE_EVT_SOURCE,
116 "Adding event loop source for fd=%d", fd);
117
118 // we need a bridge to wxFDIODispatcher
119 //
120 // TODO: refactor the code so that only wxEventLoopSourceHandler is used
121 wxScopedPtr<wxFDIOHandler>
122 fdioHandler(new wxFDIOEventLoopSourceHandler(handler));
123
124 if ( !wxFDIODispatcher::Get()->RegisterFD(fd, fdioHandler.get(), flags) )
125 return NULL;
126
127 return new wxUnixEventLoopSource(wxFDIODispatcher::Get(), fdioHandler.release(),
128 fd, handler, flags);
129 }
130};
131
132wxEventLoopSourcesManagerBase* wxAppTraits::GetEventLoopSourcesManager()
133{
134 static wxConsoleEventLoopSourcesManager s_eventLoopSourcesManager;
135
136 return &s_eventLoopSourcesManager;
137}
138
139wxUnixEventLoopSource::~wxUnixEventLoopSource()
140{
141 wxLogTrace(wxTRACE_EVT_SOURCE,
142 "Removing event loop source for fd=%d", m_fd);
143
144 m_dispatcher->UnregisterFD(m_fd);
145
146 delete m_fdioHandler;
147}
148
149#endif // wxUSE_EVENTLOOP_SOURCE
150
151//-----------------------------------------------------------------------------
152// events dispatch and loop handling
153//-----------------------------------------------------------------------------
154
155bool wxConsoleEventLoop::Pending() const
156{
157 if ( m_dispatcher->HasPending() )
158 return true;
159
160#if wxUSE_TIMER
161 wxUsecClock_t nextTimer;
162 if ( wxTimerScheduler::Get().GetNext(&nextTimer) &&
163 !wxMilliClockToLong(nextTimer) )
164 return true;
165#endif // wxUSE_TIMER
166
167 return false;
168}
169
170bool wxConsoleEventLoop::Dispatch()
171{
172 DispatchTimeout(static_cast<unsigned long>(
173 wxFDIODispatcher::TIMEOUT_INFINITE));
174
175 return true;
176}
177
178int wxConsoleEventLoop::DispatchTimeout(unsigned long timeout)
179{
180#if wxUSE_TIMER
181 // check if we need to decrease the timeout to account for a timer
182 wxUsecClock_t nextTimer;
183 if ( wxTimerScheduler::Get().GetNext(&nextTimer) )
184 {
185 unsigned long timeUntilNextTimer = wxMilliClockToLong(nextTimer / 1000);
186 if ( timeUntilNextTimer < timeout )
187 timeout = timeUntilNextTimer;
188 }
189#endif // wxUSE_TIMER
190
191 bool hadEvent = m_dispatcher->Dispatch(timeout) > 0;
192
193#if wxUSE_TIMER
194 if ( wxTimerScheduler::Get().NotifyExpired() )
195 hadEvent = true;
196#endif // wxUSE_TIMER
197
198 return hadEvent ? 1 : -1;
199}
200
201void wxConsoleEventLoop::WakeUp()
202{
203 m_wakeupPipe->WakeUp();
204}
205
206void wxConsoleEventLoop::OnNextIteration()
207{
208 // call the signal handlers for any signals we caught recently
209 wxTheApp->CheckSignal();
210}
211
212
213wxEventLoopBase *wxConsoleAppTraits::CreateEventLoop()
214{
215 return new wxEventLoop();
216}
217
218#endif // wxUSE_CONSOLE_EVENTLOOP