]> git.saurik.com Git - wxWidgets.git/blame - src/unix/epolldispatcher.cpp
gtk version check should be runtime, not compile time
[wxWidgets.git] / src / unix / epolldispatcher.cpp
CommitLineData
b46b1d59
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/common/epolldispatcher.cpp
3// Purpose: implements dispatcher for epoll_wait() call
4// Author: Lukasz Michalski
5// Created: April 2007
6// RCS-ID: $Id$
7// Copyright: (c) 2007 Lukasz Michalski
8// License: 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#ifdef HAVE_SYS_EPOLL_H
23
24#include "wx/unix/private/epolldispatcher.h"
25#include "wx/unix/private.h"
b46b1d59
VZ
26#include "wx/module.h"
27
b5ef33b2
VS
28#ifndef WX_PRECOMP
29 #include "wx/log.h"
30 #include "wx/intl.h"
31#endif
32
b46b1d59
VZ
33#include <sys/epoll.h>
34#include <errno.h>
35
36#define wxEpollDispatcher_Trace wxT("epolldispatcher")
37
38static wxEpollDispatcher *gs_epollDispatcher = NULL;
39
40// ============================================================================
41// implementation
42// ============================================================================
43
44// helper: return EPOLLxxx mask corresponding to the given flags (and also log
45// debugging messages about it)
46static uint32_t GetEpollMask(int flags, int fd)
47{
48 uint32_t ep = 0;
49
50 if ( flags & wxFDIO_INPUT )
51 {
52 ep |= EPOLLIN;
53 wxLogTrace(wxEpollDispatcher_Trace,
54 _T("Registered fd %d for input events"), fd);
55 }
56
57 if ( flags & wxFDIO_OUTPUT )
58 {
59 ep |= EPOLLOUT;
60 wxLogTrace(wxEpollDispatcher_Trace,
61 _T("Registered fd %d for output events"), fd);
62 }
63
64 if ( flags & wxFDIO_EXCEPTION )
65 {
66 ep |= EPOLLERR | EPOLLHUP;
67 wxLogTrace(wxEpollDispatcher_Trace,
68 _T("Registered fd %d for exceptional events"), fd);
69 }
70
71 return ep;
72}
73
74// ----------------------------------------------------------------------------
75// wxEpollDispatcher
76// ----------------------------------------------------------------------------
77
78wxEpollDispatcher::wxEpollDispatcher()
79{
80 m_epollDescriptor = epoll_create(1024);
81 if ( m_epollDescriptor == -1 )
82 {
83 wxLogSysError(_("Failed to create epoll descriptor"));
84 }
85}
86
87bool wxEpollDispatcher::RegisterFD(int fd, wxFDIOHandler* handler, int flags)
88{
89 if ( !wxFDIODispatcher::RegisterFD(fd, handler, flags) )
90 return false;
91
92 epoll_event ev;
93 ev.events = GetEpollMask(flags, fd);
94 ev.data.ptr = handler;
95
96 const int ret = epoll_ctl(m_epollDescriptor, EPOLL_CTL_ADD, fd, &ev);
97 if ( ret != 0 )
98 {
99 wxLogSysError(_("Failed to add descriptor %d to epoll descriptor %d"),
100 fd, m_epollDescriptor);
101
102 return false;
103 }
104
105 return true;
106}
107
108bool wxEpollDispatcher::ModifyFD(int fd, wxFDIOHandler* handler, int flags)
109{
110 if ( !wxFDIODispatcher::ModifyFD(fd, handler, flags) )
111 return false;
112
113 epoll_event ev;
114 ev.events = GetEpollMask(flags, fd);
115 ev.data.ptr = handler;
116
117 const int ret = epoll_ctl(m_epollDescriptor, EPOLL_CTL_MOD, fd, &ev);
118 if ( ret != 0 )
119 {
120 wxLogSysError(_("Failed to modify descriptor %d in epoll descriptor %d"),
121 fd, m_epollDescriptor);
122
123 return false;
124 }
125
126 return true;
127}
128
129wxFDIOHandler *wxEpollDispatcher::UnregisterFD(int fd, int flags)
130{
131 wxFDIOHandler * const handler = wxFDIODispatcher::UnregisterFD(fd, flags);
132 if ( !handler )
133 return NULL;
134
135 epoll_event ev;
136 ev.events = 0;
137 ev.data.ptr = NULL;
138
139 if ( epoll_ctl(m_epollDescriptor, EPOLL_CTL_DEL, fd, &ev) != 0 )
140 {
141 wxLogSysError(_("Failed to unregister descriptor %d from epoll descriptor %d"),
142 fd, m_epollDescriptor);
143 }
144
145 return handler;
146}
147
148void wxEpollDispatcher::RunLoop(int timeout)
149{
150 epoll_event events[16];
151
152 const int e_num = epoll_wait
153 (
154 m_epollDescriptor,
155 events,
156 WXSIZEOF(events),
157 timeout == TIMEOUT_INFINITE ? -1 : timeout
158 );
159
160 if ( e_num == -1 )
161 {
162 if ( errno != EINTR )
163 {
164 wxLogSysError(_("Waiting for IO on epoll descriptor %d failed"),
165 m_epollDescriptor);
166 return;
167 }
168 }
169
170 for ( epoll_event *p = events; p < events + e_num; p++ )
171 {
172 wxFDIOHandler * const handler = (wxFDIOHandler *)(p->data.ptr);
173 if ( !handler )
174 {
175 wxFAIL_MSG( _T("NULL handler in epoll_event?") );
176 continue;
177 }
178
179 if ( p->events & EPOLLIN )
180 handler->OnReadWaiting();
181
182 if ( p->events & EPOLLOUT )
183 handler->OnWriteWaiting();
184
185 if ( p->events & (EPOLLERR | EPOLLHUP) )
186 handler->OnExceptionWaiting();
187 }
188}
189
190/* static */
191wxEpollDispatcher *wxEpollDispatcher::Get()
192{
193 if ( !gs_epollDispatcher )
194 {
195 gs_epollDispatcher = new wxEpollDispatcher;
196 if ( !gs_epollDispatcher->IsOk() )
197 {
198 delete gs_epollDispatcher;
199 gs_epollDispatcher = NULL;
200 }
201 }
202
203 return gs_epollDispatcher;
204}
205
206// ----------------------------------------------------------------------------
207// wxEpollDispatcherModule
208// ----------------------------------------------------------------------------
209
210class wxEpollDispatcherModule : public wxModule
211{
212public:
213 wxEpollDispatcherModule() { }
214
215 virtual bool OnInit() { return true; }
216 virtual void OnExit() { wxDELETE(gs_epollDispatcher); }
217
218 DECLARE_DYNAMIC_CLASS(wxEpollDispatcherModule)
219};
220
221IMPLEMENT_DYNAMIC_CLASS(wxEpollDispatcherModule, wxModule)
222
223#endif // HAVE_SYS_EPOLL_H