X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/86c5b12b21333e9817bd2d0c21458308390e1524..ad653fa23069c5d9378247084f03c9a718c3ad62:/src/common/socketiohandler.cpp diff --git a/src/common/socketiohandler.cpp b/src/common/socketiohandler.cpp index baa797a74e..cadb78f4ec 100644 --- a/src/common/socketiohandler.cpp +++ b/src/common/socketiohandler.cpp @@ -6,7 +6,7 @@ // RCS-ID: $Id$ // Copyright: (c) 2006 Angel vidal // (c) 2007 Vadim Zeitlin -// License: wxWindows licence +// Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// // ============================================================================ @@ -20,138 +20,94 @@ // for compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" -#if wxUSE_SOCKETS && wxUSE_SELECT_DISPATCHER +#ifdef __BORLANDC__ + #pragma hdrstop +#endif +#if wxUSE_SOCKETS + +#include "wx/app.h" #include "wx/apptrait.h" -#include "wx/unix/private.h" -#include "wx/private/socketiohandler.h" +#include "wx/private/socket.h" +#include "wx/link.h" // ============================================================================ -// implementation +// wxSocketFDBasedManager implementation // ============================================================================ -// ---------------------------------------------------------------------------- -// wxSocketImplFDIO -// ---------------------------------------------------------------------------- - -class wxSocketImplFDIO : public wxSocketImplUnix +bool wxSocketFDBasedManager::OnInit() { -public: - wxSocketImplFDIO(wxSocketBase& wxsocket) - : wxSocketImplUnix(wxsocket) - { - m_handler = NULL; - } - - virtual ~wxSocketImplFDIO() - { - delete m_handler; - } - - wxSocketIOHandler *m_handler; -}; + wxAppTraits * const traits = wxApp::GetTraitsIfExists(); + if ( !traits ) + return false; -// ---------------------------------------------------------------------------- -// wxSocketSelectManager -// ---------------------------------------------------------------------------- - -class wxSocketSelectManager : public wxSocketFDBasedManager -{ -public: - virtual wxSocketImpl *CreateSocket(wxSocketBase& wxsocket) - { - return new wxSocketImplFDIO(wxsocket); - } - - virtual void Install_Callback(wxSocketImpl *socket, wxSocketNotify event); - virtual void Uninstall_Callback(wxSocketImpl *socket, wxSocketNotify event); -}; + m_fdioManager = traits->GetFDIOManager(); + return m_fdioManager != NULL; +} -void wxSocketSelectManager::Install_Callback(wxSocketImpl *socket_, - wxSocketNotify event) +void wxSocketFDBasedManager::Install_Callback(wxSocketImpl *socket_, + wxSocketNotify event) { - wxSocketImplFDIO * const socket = static_cast(socket_); + wxSocketImplUnix * const + socket = static_cast(socket_); - const int fd = socket->m_fd; + wxCHECK_RET( socket->m_fd != -1, + "shouldn't be called on invalid socket" ); - if ( fd == -1 ) - return; + const wxFDIOManager::Direction d = GetDirForEvent(socket, event); - const SocketDir d = GetDirForEvent(socket, event); + int& fd = FD(socket, d); + if ( fd != -1 ) + m_fdioManager->RemoveInput(socket, fd, d); - wxFDIODispatcher * const dispatcher = wxFDIODispatcher::Get(); - if ( !dispatcher ) - return; + fd = m_fdioManager->AddInput(socket, socket->m_fd, d); +} - wxSocketIOHandler *& handler = socket->m_handler; +void wxSocketFDBasedManager::Uninstall_Callback(wxSocketImpl *socket_, + wxSocketNotify event) +{ + wxSocketImplUnix * const + socket = static_cast(socket_); - // we should register the new handlers but modify the existing ones in place - bool registerHandler; - if ( handler ) - { - registerHandler = false; - } - else // no existing handler - { - registerHandler = true; - handler = new wxSocketIOHandler(socket); - } + const wxFDIOManager::Direction d = GetDirForEvent(socket, event); - FD(socket, d) = fd; - if (d == FD_INPUT) + int& fd = FD(socket, d); + if ( fd != -1 ) { - handler->AddFlag(wxFDIO_INPUT); + m_fdioManager->RemoveInput(socket, fd, d); + fd = -1; } - else - { - handler->AddFlag(wxFDIO_OUTPUT); - } - - if ( registerHandler ) - dispatcher->RegisterFD(fd, handler, handler->GetFlags()); - else - dispatcher->ModifyFD(fd, handler, handler->GetFlags()); } -void wxSocketSelectManager::Uninstall_Callback(wxSocketImpl *socket_, - wxSocketNotify event) +wxFDIOManager::Direction +wxSocketFDBasedManager::GetDirForEvent(wxSocketImpl *socket, + wxSocketNotify event) { - wxSocketImplFDIO * const socket = static_cast(socket_); - - const SocketDir d = GetDirForEvent(socket, event); - - const int fd = FD(socket, d); - if ( fd == -1 ) - return; - - FD(socket, d) = -1; - - const wxFDIODispatcherEntryFlags - flag = d == FD_INPUT ? wxFDIO_INPUT : wxFDIO_OUTPUT; - - wxFDIODispatcher * const dispatcher = wxFDIODispatcher::Get(); - if ( !dispatcher ) - return; - - wxSocketIOHandler *& handler = socket->m_handler; - if ( handler ) + switch ( event ) { - handler->RemoveFlag(flag); - - if ( !handler->GetFlags() ) - { - dispatcher->UnregisterFD(fd); - delete handler; - socket->m_handler = NULL; - } - else - { - dispatcher->ModifyFD(fd, handler, handler->GetFlags()); - } - } - else - { - dispatcher->UnregisterFD(fd); + default: + wxFAIL_MSG( "unknown socket event" ); + return wxFDIOManager::INPUT; // we must return something + + case wxSOCKET_LOST: + wxFAIL_MSG( "unexpected socket event" ); + return wxFDIOManager::INPUT; // as above + + case wxSOCKET_INPUT: + return wxFDIOManager::INPUT; + + case wxSOCKET_OUTPUT: + return wxFDIOManager::OUTPUT; + + case wxSOCKET_CONNECTION: + // for server sockets we're interested in events indicating + // that a new connection is pending, i.e. that accept() will + // succeed and this is indicated by socket becoming ready for + // reading, while for the other ones we're interested in the + // completion of non-blocking connect() which is indicated by + // the socket becoming ready for writing + return socket->IsServer() ? wxFDIOManager::INPUT + : wxFDIOManager::OUTPUT; } } @@ -163,9 +119,13 @@ static struct ManagerSetter { ManagerSetter() { - static wxSocketSelectManager s_manager; + static wxSocketFDBasedManager s_manager; wxAppTraits::SetDefaultSocketManager(&s_manager); } } gs_managerSetter; + +// see the relative linker macro in socket.cpp +wxFORCE_LINK_THIS_MODULE( socketiohandler ); + #endif // wxUSE_SOCKETS