X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/30c45bdd06c4174d28f62133692733d447d008ea..f94a77989a5f313d6bfd818a70e583d2a8d58171:/src/common/gsocketiohandler.cpp?ds=sidebyside diff --git a/src/common/gsocketiohandler.cpp b/src/common/gsocketiohandler.cpp index 35fd89640e..f31a6ecf99 100644 --- a/src/common/gsocketiohandler.cpp +++ b/src/common/gsocketiohandler.cpp @@ -2,10 +2,10 @@ // Name: src/common/gsocketiohandler.cpp // Purpose: implementation of wxFDIOHandler for GSocket // Author: Angel Vidal, Lukasz Michalski -// Modified by: // Created: 08.24.06 // RCS-ID: $Id$ // Copyright: (c) 2006 Angel vidal +// (c) 2007 Vadim Zeitlin // License: wxWindows licence /////////////////////////////////////////////////////////////////////////////// @@ -20,180 +20,116 @@ // for compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" -#if wxUSE_SOCKETS +#if wxUSE_SOCKETS && wxUSE_SELECT_DISPATCHER -#include "wx/private/gsocketiohandler.h" +#include "wx/apptrait.h" #include "wx/unix/private.h" -#include "wx/gsocket.h" -#include "wx/unix/gsockunx.h" +#include "wx/private/gsocketiohandler.h" // ============================================================================ // implementation // ============================================================================ // ---------------------------------------------------------------------------- -// wxGSocketIOHandler +// GSocketSelectManager // ---------------------------------------------------------------------------- -wxGSocketIOHandler::wxGSocketIOHandler(GSocket* socket) - : m_socket(socket), - m_flags(0) -{ - -}; - -void wxGSocketIOHandler::OnReadWaiting(int fd) -{ - m_socket->Detected_Read(); -}; - -void wxGSocketIOHandler::OnWriteWaiting(int fd) -{ - m_socket->Detected_Write(); -}; - -void wxGSocketIOHandler::OnExceptionWaiting(int fd) +class GSocketSelectManager : public GSocketFDBasedManager { - m_socket->Detected_Read(); +public: + virtual void Install_Callback(GSocket *socket, GSocketEvent event); + virtual void Uninstall_Callback(GSocket *socket, GSocketEvent event); }; -int wxGSocketIOHandler::GetFlags() const -{ - return m_flags; -}; - - -void wxGSocketIOHandler::RemoveFlag(wxSelectDispatcherEntryFlags flag) -{ - m_flags &= ~flag; -}; - -void wxGSocketIOHandler::AddFlag(wxSelectDispatcherEntryFlags flag) -{ - m_flags |= flag; -}; - -// ---------------------------------------------------------------------------- -// GSocket interface -// ---------------------------------------------------------------------------- - -bool GSocketGUIFunctionsTableConcrete::CanUseEventLoop() -{ - return true; -} - -bool GSocketGUIFunctionsTableConcrete::OnInit() -{ - return true; +void GSocketSelectManager::Install_Callback(GSocket *socket, + GSocketEvent event) +{ + const int fd = socket->m_fd; + + if ( fd == -1 ) + return; + + const SocketDir d = GetDirForEvent(socket, event); + + wxFDIODispatcher * const dispatcher = wxFDIODispatcher::Get(); + if ( !dispatcher ) + return; + + wxGSocketIOHandler *& handler = socket->m_handler; + + // 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 wxGSocketIOHandler(socket); + } + + FD(socket, d) = fd; + if (d == FD_INPUT) + { + handler->AddFlag(wxFDIO_INPUT); + } + else + { + handler->AddFlag(wxFDIO_OUTPUT); + } + + if ( registerHandler ) + dispatcher->RegisterFD(fd, handler, handler->GetFlags()); + else + dispatcher->ModifyFD(fd, handler, handler->GetFlags()); } -void GSocketGUIFunctionsTableConcrete::OnExit() -{ +void GSocketSelectManager::Uninstall_Callback(GSocket *socket, + GSocketEvent event) +{ + 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; + + wxGSocketIOHandler *& handler = socket->m_handler; + if ( handler ) + { + 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); + } } -bool GSocketGUIFunctionsTableConcrete::Init_Socket(GSocket *socket) +GSocketManager *wxAppTraits::GetSocketManager() { - int *m_id; + static GSocketSelectManager s_manager; - socket->m_gui_dependent = (char *)malloc(sizeof(int)*2); - m_id = (int *)(socket->m_gui_dependent); - - m_id[0] = -1; - m_id[1] = -1; - - return true; -} - -void GSocketGUIFunctionsTableConcrete::Destroy_Socket(GSocket *socket) -{ - free(socket->m_gui_dependent); -} - -void GSocketGUIFunctionsTableConcrete::Install_Callback(GSocket *socket, - GSocketEvent event) -{ - int *m_id = (int *)(socket->m_gui_dependent); - int c; - - if (socket->m_fd == -1) - return; - - switch (event) - { - case GSOCK_LOST: /* fall-through */ - case GSOCK_INPUT: c = 0; break; - case GSOCK_OUTPUT: c = 1; break; - case GSOCK_CONNECTION: c = ((socket->m_server) ? 0 : 1); break; - default: return; - } - - wxGSocketIOHandler* handler = (wxGSocketIOHandler*)(wxSelectDispatcher::Get().FindHandler(socket->m_fd)); - if (handler == NULL) - { - handler = new wxGSocketIOHandler(socket); - }; - - if (c == 0) - { - m_id[0] = socket->m_fd; - handler->AddFlag(wxSelectInput); - } - else - { - m_id[1] = socket->m_fd; - handler->AddFlag(wxSelectOutput); - } - - wxSelectDispatcher::Get().RegisterFD(socket->m_fd,handler,handler->GetFlags()); -} - -void GSocketGUIFunctionsTableConcrete::Uninstall_Callback(GSocket *socket, - GSocketEvent event) -{ - int *m_id = (int *)(socket->m_gui_dependent); - int c; - - switch (event) - { - case GSOCK_LOST: /* fall-through */ - case GSOCK_INPUT: c = 0; break; - case GSOCK_OUTPUT: c = 1; break; - case GSOCK_CONNECTION: c = ((socket->m_server) ? 0 : 1); break; - default: return; - } - - wxGSocketIOHandler* handler = NULL; - if ( m_id[c] != -1 ) - { - if ( c == 0 ) - { - handler = (wxGSocketIOHandler*)wxSelectDispatcher::Get().UnregisterFD(m_id[c], wxSelectInput); - if (handler != NULL) - handler->RemoveFlag(wxSelectInput); - } - else - { - handler = (wxGSocketIOHandler*)wxSelectDispatcher::Get().UnregisterFD(m_id[c], wxSelectOutput); - if (handler != NULL) - handler->RemoveFlag(wxSelectOutput); - } - if (handler && handler->GetFlags() == 0) - delete handler; - } - - m_id[c] = -1; -} - -void GSocketGUIFunctionsTableConcrete::Enable_Events(GSocket *socket) -{ - Install_Callback(socket, GSOCK_INPUT); - Install_Callback(socket, GSOCK_OUTPUT); -} - -void GSocketGUIFunctionsTableConcrete::Disable_Events(GSocket *socket) -{ - Uninstall_Callback(socket, GSOCK_INPUT); - Uninstall_Callback(socket, GSOCK_OUTPUT); + return &s_manager; } #endif // wxUSE_SOCKETS