// RCS-ID: $Id$
// Copyright: (c) 2006 Angel vidal
// (c) 2007 Vadim Zeitlin <vadim@wxwidgets.org>
-// License: wxWindows licence
+// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// ============================================================================
// 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<wxSocketImplFDIO *>(socket_);
+ wxSocketImplUnix * const
+ socket = static_cast<wxSocketImplUnix *>(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<wxSocketImplUnix *>(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<wxSocketImplFDIO *>(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;
}
}
{
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