]>
git.saurik.com Git - wxWidgets.git/blob - src/common/selectdispatcher.cpp
ffcf38717912bd16ad42dec7075fbaf77bb1a761
   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 // ---------------------------------------------------------------------------- 
 134 bool wxSelectDispatcher::RegisterFD(int fd
, wxFDIOHandler 
*handler
, int flags
) 
 136     if ( !wxMappedFDIODispatcher::RegisterFD(fd
, handler
, flags
) ) 
 139     if ( !m_sets
.SetFD(fd
, flags
) ) 
 145     wxLogTrace(wxSelectDispatcher_Trace
, 
 146                 _T("Registered fd %d: input:%d, output:%d, exceptional:%d"), fd
, (flags 
& wxFDIO_INPUT
) == wxFDIO_INPUT
, (flags 
& wxFDIO_OUTPUT
), (flags 
& wxFDIO_EXCEPTION
) == wxFDIO_EXCEPTION
); 
 150 bool wxSelectDispatcher::ModifyFD(int fd
, wxFDIOHandler 
*handler
, int flags
) 
 152     if ( !wxMappedFDIODispatcher::ModifyFD(fd
, handler
, flags
) ) 
 155     wxASSERT_MSG( fd 
<= m_maxFD
, _T("logic error: registered fd > m_maxFD?") ); 
 157     wxLogTrace(wxSelectDispatcher_Trace
, 
 158                 _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
); 
 159     return m_sets
.SetFD(fd
, flags
); 
 162 bool wxSelectDispatcher::UnregisterFD(int fd
) 
 166     if ( !wxMappedFDIODispatcher::UnregisterFD(fd
) ) 
 169     // remove the handler if we don't need it any more 
 170     if ( !m_sets
.HasFD(fd
) ) 
 174             // need to find new max fd 
 176             for ( wxFDIOHandlerMap::const_iterator it 
= m_handlers
.begin(); 
 177                   it 
!= m_handlers
.end(); 
 180                 if ( it
->first 
> m_maxFD 
) 
 188     wxLogTrace(wxSelectDispatcher_Trace
, 
 189                 _T("Removed fd %d, current max: %d"), fd
, m_maxFD
); 
 193 void wxSelectDispatcher::ProcessSets(const wxSelectSets
& sets
) 
 195     for ( int fd 
= 0; fd 
<= m_maxFD
; fd
++ ) 
 197         if ( !sets
.HasFD(fd
) ) 
 200         wxFDIOHandler 
* const handler 
= FindHandler(fd
); 
 203             wxFAIL_MSG( _T("NULL handler in wxSelectDispatcher?") ); 
 207         sets
.Handle(fd
, *handler
); 
 211 void wxSelectDispatcher::Dispatch(int timeout
) 
 215     if ( timeout 
!= TIMEOUT_INFINITE 
) 
 219         tv
.tv_usec 
= timeout
*1000; 
 226     wxSelectSets sets 
= m_sets
; 
 228     const int ret 
= sets
.Select(m_maxFD 
+ 1, ptv
); 
 232             if ( errno 
!= EINTR 
) 
 234                 wxLogSysError(_("Failed to monitor I/O channels")); 
 239             // timeout expired without anything happening 
 247 #endif // wxUSE_SELECT_DISPATCHER