]> git.saurik.com Git - wxWidgets.git/blame - src/unix/epolldispatcher.cpp
Correct EnsureVisible() to show last item entirely
[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
9550ee98 22#if wxUSE_EPOLL_DISPATCHER
b46b1d59
VZ
23
24#include "wx/unix/private/epolldispatcher.h"
25#include "wx/unix/private.h"
b46b1d59 26
b5ef33b2
VS
27#ifndef WX_PRECOMP
28 #include "wx/log.h"
29 #include "wx/intl.h"
30#endif
31
b46b1d59
VZ
32#include <sys/epoll.h>
33#include <errno.h>
98883bca 34#include <unistd.h>
b46b1d59
VZ
35
36#define wxEpollDispatcher_Trace wxT("epolldispatcher")
37
b46b1d59
VZ
38// ============================================================================
39// implementation
40// ============================================================================
41
42// helper: return EPOLLxxx mask corresponding to the given flags (and also log
43// debugging messages about it)
44static uint32_t GetEpollMask(int flags, int fd)
45{
46 uint32_t ep = 0;
47
48 if ( flags & wxFDIO_INPUT )
49 {
50 ep |= EPOLLIN;
51 wxLogTrace(wxEpollDispatcher_Trace,
52 _T("Registered fd %d for input events"), fd);
53 }
54
55 if ( flags & wxFDIO_OUTPUT )
56 {
57 ep |= EPOLLOUT;
58 wxLogTrace(wxEpollDispatcher_Trace,
59 _T("Registered fd %d for output events"), fd);
60 }
61
62 if ( flags & wxFDIO_EXCEPTION )
63 {
64 ep |= EPOLLERR | EPOLLHUP;
65 wxLogTrace(wxEpollDispatcher_Trace,
66 _T("Registered fd %d for exceptional events"), fd);
67 }
68
69 return ep;
70}
71
72// ----------------------------------------------------------------------------
73// wxEpollDispatcher
74// ----------------------------------------------------------------------------
75
5e1eac14
VZ
76/* static */
77wxEpollDispatcher *wxEpollDispatcher::Create()
b46b1d59 78{
5e1eac14
VZ
79 int epollDescriptor = epoll_create(1024);
80 if ( epollDescriptor == -1 )
b46b1d59
VZ
81 {
82 wxLogSysError(_("Failed to create epoll descriptor"));
5e1eac14 83 return NULL;
b46b1d59 84 }
985acf87 85
5e1eac14
VZ
86 return new wxEpollDispatcher(epollDescriptor);
87}
88
89wxEpollDispatcher::wxEpollDispatcher(int epollDescriptor)
90{
91 wxASSERT_MSG( epollDescriptor != -1, _T("invalid descriptor") );
92
93 m_epollDescriptor = epollDescriptor;
b46b1d59
VZ
94}
95
d31a4a84
VZ
96wxEpollDispatcher::~wxEpollDispatcher()
97{
98 if ( close(m_epollDescriptor) != 0 )
99 {
100 wxLogSysError(_("Error closing epoll descriptor"));
101 }
102}
103
b46b1d59
VZ
104bool wxEpollDispatcher::RegisterFD(int fd, wxFDIOHandler* handler, int flags)
105{
b46b1d59
VZ
106 epoll_event ev;
107 ev.events = GetEpollMask(flags, fd);
108 ev.data.ptr = handler;
109
110 const int ret = epoll_ctl(m_epollDescriptor, EPOLL_CTL_ADD, fd, &ev);
111 if ( ret != 0 )
112 {
113 wxLogSysError(_("Failed to add descriptor %d to epoll descriptor %d"),
114 fd, m_epollDescriptor);
115
116 return false;
117 }
118
119 return true;
120}
121
122bool wxEpollDispatcher::ModifyFD(int fd, wxFDIOHandler* handler, int flags)
123{
b46b1d59
VZ
124 epoll_event ev;
125 ev.events = GetEpollMask(flags, fd);
126 ev.data.ptr = handler;
127
128 const int ret = epoll_ctl(m_epollDescriptor, EPOLL_CTL_MOD, fd, &ev);
129 if ( ret != 0 )
130 {
131 wxLogSysError(_("Failed to modify descriptor %d in epoll descriptor %d"),
132 fd, m_epollDescriptor);
133
134 return false;
135 }
136
137 return true;
138}
139
af57c51a 140bool wxEpollDispatcher::UnregisterFD(int fd)
b46b1d59 141{
b46b1d59
VZ
142 epoll_event ev;
143 ev.events = 0;
144 ev.data.ptr = NULL;
145
146 if ( epoll_ctl(m_epollDescriptor, EPOLL_CTL_DEL, fd, &ev) != 0 )
147 {
148 wxLogSysError(_("Failed to unregister descriptor %d from epoll descriptor %d"),
149 fd, m_epollDescriptor);
150 }
985acf87 151
ad8d42f8 152 return true;
b46b1d59
VZ
153}
154
7523de90 155void wxEpollDispatcher::Dispatch(int timeout)
b46b1d59
VZ
156{
157 epoll_event events[16];
158
159 const int e_num = epoll_wait
160 (
161 m_epollDescriptor,
162 events,
163 WXSIZEOF(events),
164 timeout == TIMEOUT_INFINITE ? -1 : timeout
165 );
166
167 if ( e_num == -1 )
168 {
169 if ( errno != EINTR )
170 {
171 wxLogSysError(_("Waiting for IO on epoll descriptor %d failed"),
172 m_epollDescriptor);
173 return;
174 }
175 }
176
177 for ( epoll_event *p = events; p < events + e_num; p++ )
178 {
179 wxFDIOHandler * const handler = (wxFDIOHandler *)(p->data.ptr);
180 if ( !handler )
181 {
182 wxFAIL_MSG( _T("NULL handler in epoll_event?") );
183 continue;
184 }
185
186 if ( p->events & EPOLLIN )
187 handler->OnReadWaiting();
7523de90 188 else if ( p->events & EPOLLOUT )
b46b1d59 189 handler->OnWriteWaiting();
7523de90 190 else if ( p->events & (EPOLLERR | EPOLLHUP) )
b46b1d59
VZ
191 handler->OnExceptionWaiting();
192 }
193}
194
a1873279 195#endif // wxUSE_EPOLL_DISPATCHER