]>
git.saurik.com Git - wxWidgets.git/blob - src/common/selectdispatcher.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/selectdispatcher.cpp
3 // Purpose: implements dispatcher for select() call
4 // Author: Lukasz Michalski and Vadim Zeitlin
5 // Created: December 2006
7 // Copyright: (c) 2006 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_SELECT_DISPATCHER
24 #include "wx/private/selectdispatcher.h"
25 #include "wx/unix/private.h"
33 #if defined(HAVE_SYS_SELECT_H) || defined(__WATCOMC__)
35 #include <sys/select.h>
40 #define wxSelectDispatcher_Trace wxT("selectdispatcher")
42 // ============================================================================
44 // ============================================================================
46 // ----------------------------------------------------------------------------
48 // ----------------------------------------------------------------------------
50 int wxSelectSets::ms_flags
[wxSelectSets::Max
] =
57 const char *wxSelectSets::ms_names
[wxSelectSets::Max
] =
64 wxSelectSets::Callback
wxSelectSets::ms_handlers
[wxSelectSets::Max
] =
66 &wxFDIOHandler::OnReadWaiting
,
67 &wxFDIOHandler::OnWriteWaiting
,
68 &wxFDIOHandler::OnExceptionWaiting
,
71 wxSelectSets::wxSelectSets()
73 for ( int n
= 0; n
< Max
; n
++ )
79 bool wxSelectSets::HasFD(int fd
) const
81 for ( int n
= 0; n
< Max
; n
++ )
83 if ( wxFD_ISSET(fd
, (fd_set
*) &m_fds
[n
]) )
90 bool wxSelectSets::SetFD(int fd
, int flags
)
92 wxCHECK_MSG( fd
>= 0, false, _T("invalid descriptor") );
94 for ( int n
= 0; n
< Max
; n
++ )
96 if ( flags
& ms_flags
[n
] )
98 wxFD_SET(fd
, &m_fds
[n
]);
100 else if ( wxFD_ISSET(fd
, (fd_set
*) &m_fds
[n
]) )
102 wxFD_CLR(fd
, &m_fds
[n
]);
109 int wxSelectSets::Select(int nfds
, struct timeval
*tv
)
111 return select(nfds
, &m_fds
[Read
], &m_fds
[Write
], &m_fds
[Except
], tv
);
114 void wxSelectSets::Handle(int fd
, wxFDIOHandler
& handler
) const
116 for ( int n
= 0; n
< Max
; n
++ )
118 if ( wxFD_ISSET(fd
, (fd_set
*) &m_fds
[n
]) )
120 wxLogTrace(wxSelectDispatcher_Trace
,
121 _T("Got %s event on fd %d"), ms_names
[n
], fd
);
122 (handler
.*ms_handlers
[n
])();
123 // callback can modify sets and destroy handler
124 // this forces that one event can be processed at one time
130 // ----------------------------------------------------------------------------
131 // wxSelectDispatcher
132 // ----------------------------------------------------------------------------
135 wxSelectDispatcher
*wxSelectDispatcher::Create()
137 return new wxSelectDispatcher
;
140 wxSelectDispatcher::wxSelectDispatcher()
145 bool wxSelectDispatcher::RegisterFD(int fd
, wxFDIOHandler
*handler
, int flags
)
147 if ( !wxMappedFDIODispatcher::RegisterFD(fd
, handler
, flags
) )
150 if ( !m_sets
.SetFD(fd
, flags
) )
156 wxLogTrace(wxSelectDispatcher_Trace
,
157 _T("Registered fd %d: input:%d, output:%d, exceptional:%d"), fd
, (flags
& wxFDIO_INPUT
) == wxFDIO_INPUT
, (flags
& wxFDIO_OUTPUT
), (flags
& wxFDIO_EXCEPTION
) == wxFDIO_EXCEPTION
);
161 bool wxSelectDispatcher::ModifyFD(int fd
, wxFDIOHandler
*handler
, int flags
)
163 if ( !wxMappedFDIODispatcher::ModifyFD(fd
, handler
, flags
) )
166 wxASSERT_MSG( fd
<= m_maxFD
, _T("logic error: registered fd > m_maxFD?") );
168 wxLogTrace(wxSelectDispatcher_Trace
,
169 _T("Modified fd %d: input:%d, output:%d, exceptional:%d"), fd
, (flags
& wxFDIO_INPUT
) == wxFDIO_INPUT
, (flags
& wxFDIO_OUTPUT
) == wxFDIO_OUTPUT
, (flags
& wxFDIO_EXCEPTION
) == wxFDIO_EXCEPTION
);
170 return m_sets
.SetFD(fd
, flags
);
173 bool wxSelectDispatcher::UnregisterFD(int fd
)
177 if ( !wxMappedFDIODispatcher::UnregisterFD(fd
) )
180 // remove the handler if we don't need it any more
181 if ( !m_sets
.HasFD(fd
) )
185 // need to find new max fd
187 for ( wxFDIOHandlerMap::const_iterator it
= m_handlers
.begin();
188 it
!= m_handlers
.end();
191 if ( it
->first
> m_maxFD
)
199 wxLogTrace(wxSelectDispatcher_Trace
,
200 _T("Removed fd %d, current max: %d"), fd
, m_maxFD
);
204 void wxSelectDispatcher::ProcessSets(const wxSelectSets
& sets
)
206 for ( int fd
= 0; fd
<= m_maxFD
; fd
++ )
208 if ( !sets
.HasFD(fd
) )
211 wxFDIOHandler
* const handler
= FindHandler(fd
);
214 wxFAIL_MSG( _T("NULL handler in wxSelectDispatcher?") );
218 sets
.Handle(fd
, *handler
);
222 void wxSelectDispatcher::Dispatch(int timeout
)
226 if ( timeout
!= TIMEOUT_INFINITE
)
230 tv
.tv_usec
= timeout
*1000;
237 wxSelectSets sets
= m_sets
;
239 const int ret
= sets
.Select(m_maxFD
+ 1, ptv
);
243 if ( errno
!= EINTR
)
245 wxLogSysError(_("Failed to monitor I/O channels"));
250 // timeout expired without anything happening
258 #endif // wxUSE_SELECT_DISPATCHER