]>
git.saurik.com Git - wxWidgets.git/blob - src/unix/epolldispatcher.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/epolldispatcher.cpp
3 // Purpose: implements dispatcher for epoll_wait() call
4 // Author: Lukasz Michalski
7 // Copyright: (c) 2007 Lukasz Michalski
8 // License: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
22 #if wxUSE_EPOLL_DISPATCHER
24 #include "wx/unix/private/epolldispatcher.h"
25 #include "wx/unix/private.h"
32 #include <sys/epoll.h>
36 #define wxEpollDispatcher_Trace wxT("epolldispatcher")
38 // ============================================================================
40 // ============================================================================
42 // helper: return EPOLLxxx mask corresponding to the given flags (and also log
43 // debugging messages about it)
44 static uint32_t GetEpollMask(int flags
, int WXUNUSED_UNLESS_DEBUG(fd
))
48 if ( flags
& wxFDIO_INPUT
)
51 wxLogTrace(wxEpollDispatcher_Trace
,
52 _T("Registered fd %d for input events"), fd
);
55 if ( flags
& wxFDIO_OUTPUT
)
58 wxLogTrace(wxEpollDispatcher_Trace
,
59 _T("Registered fd %d for output events"), fd
);
62 if ( flags
& wxFDIO_EXCEPTION
)
64 ep
|= EPOLLERR
| EPOLLHUP
;
65 wxLogTrace(wxEpollDispatcher_Trace
,
66 _T("Registered fd %d for exceptional events"), fd
);
72 // ----------------------------------------------------------------------------
74 // ----------------------------------------------------------------------------
77 wxEpollDispatcher
*wxEpollDispatcher::Create()
79 int epollDescriptor
= epoll_create(1024);
80 if ( epollDescriptor
== -1 )
82 wxLogSysError(_("Failed to create epoll descriptor"));
85 wxLogTrace(wxEpollDispatcher_Trace
,
86 _T("Epoll fd %d created"), epollDescriptor
);
87 return new wxEpollDispatcher(epollDescriptor
);
90 wxEpollDispatcher::wxEpollDispatcher(int epollDescriptor
)
92 wxASSERT_MSG( epollDescriptor
!= -1, _T("invalid descriptor") );
94 m_epollDescriptor
= epollDescriptor
;
97 wxEpollDispatcher::~wxEpollDispatcher()
99 if ( close(m_epollDescriptor
) != 0 )
101 wxLogSysError(_("Error closing epoll descriptor"));
105 bool wxEpollDispatcher::RegisterFD(int fd
, wxFDIOHandler
* handler
, int flags
)
108 ev
.events
= GetEpollMask(flags
, fd
);
109 ev
.data
.ptr
= handler
;
111 const int ret
= epoll_ctl(m_epollDescriptor
, EPOLL_CTL_ADD
, fd
, &ev
);
114 wxLogSysError(_("Failed to add descriptor %d to epoll descriptor %d"),
115 fd
, m_epollDescriptor
);
119 wxLogTrace(wxEpollDispatcher_Trace
,
120 _T("Added fd %d (handler %p) to epoll %d"), fd
, handler
, m_epollDescriptor
);
125 bool wxEpollDispatcher::ModifyFD(int fd
, wxFDIOHandler
* handler
, int flags
)
128 ev
.events
= GetEpollMask(flags
, fd
);
129 ev
.data
.ptr
= handler
;
131 const int ret
= epoll_ctl(m_epollDescriptor
, EPOLL_CTL_MOD
, fd
, &ev
);
134 wxLogSysError(_("Failed to modify descriptor %d in epoll descriptor %d"),
135 fd
, m_epollDescriptor
);
140 wxLogTrace(wxEpollDispatcher_Trace
,
141 _T("Modified fd %d (handler: %p) on epoll %d"), fd
, handler
, m_epollDescriptor
);
145 bool wxEpollDispatcher::UnregisterFD(int fd
)
151 if ( epoll_ctl(m_epollDescriptor
, EPOLL_CTL_DEL
, fd
, &ev
) != 0 )
153 wxLogSysError(_("Failed to unregister descriptor %d from epoll descriptor %d"),
154 fd
, m_epollDescriptor
);
156 wxLogTrace(wxEpollDispatcher_Trace
,
157 _T("removed fd %d from %d"), fd
, m_epollDescriptor
);
161 void wxEpollDispatcher::Dispatch(int timeout
)
163 epoll_event events
[16];
165 const int e_num
= epoll_wait
170 timeout
== TIMEOUT_INFINITE
? -1 : timeout
175 if ( errno
!= EINTR
)
177 wxLogSysError(_("Waiting for IO on epoll descriptor %d failed"),
183 for ( epoll_event
*p
= events
; p
< events
+ e_num
; p
++ )
185 wxFDIOHandler
* const handler
= (wxFDIOHandler
*)(p
->data
.ptr
);
188 wxFAIL_MSG( _T("NULL handler in epoll_event?") );
192 // note that for compatibility with wxSelectDispatcher we call
193 // OnReadWaiting() on EPOLLHUP as this is what epoll_wait() returns
194 // when the write end of a pipe is closed while with select() the
195 // remaining pipe end becomes ready for reading when this happens
196 if ( p
->events
& (EPOLLIN
| EPOLLHUP
) )
197 handler
->OnReadWaiting();
198 else if ( p
->events
& EPOLLOUT
)
199 handler
->OnWriteWaiting();
200 else if ( p
->events
& EPOLLERR
)
201 handler
->OnExceptionWaiting();
205 #endif // wxUSE_EPOLL_DISPATCHER