// 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/private/socket.h"
+#include "wx/link.h"
// ============================================================================
-// implementation
+// wxSocketFDBasedManager implementation
// ============================================================================
-// ----------------------------------------------------------------------------
-// wxSocketImplFDIO
-// ----------------------------------------------------------------------------
-
-class wxSocketImplFDIO : public wxSocketImplUnix
+bool wxSocketFDBasedManager::OnInit()
{
-public:
- wxSocketImplFDIO(wxSocketBase& wxsocket)
- : wxSocketImplUnix(wxsocket)
- {
- }
-
- int GetFlags() const { return m_flags; }
- void RemoveFlag(wxFDIODispatcherEntryFlags flag) { m_flags &= ~flag; }
- void AddFlag(wxFDIODispatcherEntryFlags flag) { m_flags |= flag; }
-
-private:
- int m_flags;
-};
-
-// ----------------------------------------------------------------------------
-// wxSocketSelectManager
-// ----------------------------------------------------------------------------
-
-class wxSocketSelectManager : public wxSocketFDBasedManager
-{
-public:
- virtual wxSocketImpl *CreateSocket(wxSocketBase& wxsocket)
- {
- return new wxSocketImplFDIO(wxsocket);
- }
+ wxAppTraits * const traits = wxApp::GetTraitsIfExists();
+ if ( !traits )
+ return false;
- 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_);
-
- const int fd = socket->m_fd;
-
- if ( fd == -1 )
- return;
-
- const SocketDir d = GetDirForEvent(socket, event);
+ wxSocketImplUnix * const
+ socket = static_cast<wxSocketImplUnix *>(socket_);
- wxFDIODispatcher * const dispatcher = wxFDIODispatcher::Get();
- if ( !dispatcher )
- return;
+ wxCHECK_RET( socket->m_fd != -1,
+ "shouldn't be called on invalid socket" );
- FD(socket, d) = fd;
+ const wxFDIOManager::Direction d = GetDirForEvent(socket, event);
- // register it when it's used for the first time, update it if it had been
- // previously registered
- const bool registerHandler = socket->GetFlags() == 0;
+ int& fd = FD(socket, d);
+ if ( fd != -1 )
+ m_fdioManager->RemoveInput(socket, fd, d);
- socket->AddFlag(d == FD_INPUT ? wxFDIO_INPUT : wxFDIO_OUTPUT);
-
- if ( registerHandler )
- dispatcher->RegisterFD(fd, socket, socket->GetFlags());
- else
- dispatcher->ModifyFD(fd, socket, socket->GetFlags());
+ fd = m_fdioManager->AddInput(socket, socket->m_fd, d);
}
-void wxSocketSelectManager::Uninstall_Callback(wxSocketImpl *socket_,
- wxSocketNotify event)
+void wxSocketFDBasedManager::Uninstall_Callback(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;
+ wxSocketImplUnix * const
+ socket = static_cast<wxSocketImplUnix *>(socket_);
- const wxFDIODispatcherEntryFlags
- flag = d == FD_INPUT ? wxFDIO_INPUT : wxFDIO_OUTPUT;
+ const wxFDIOManager::Direction d = GetDirForEvent(socket, event);
- wxFDIODispatcher * const dispatcher = wxFDIODispatcher::Get();
- if ( !dispatcher )
- return;
-
- socket->RemoveFlag(flag);
-
- if ( !socket->GetFlags() )
+ int& fd = FD(socket, d);
+ if ( fd != -1 )
{
- dispatcher->UnregisterFD(fd);
+ m_fdioManager->RemoveInput(socket, fd, d);
+ fd = -1;
}
- else
+}
+
+wxFDIOManager::Direction
+wxSocketFDBasedManager::GetDirForEvent(wxSocketImpl *socket,
+ wxSocketNotify event)
+{
+ switch ( event )
{
- dispatcher->ModifyFD(fd, socket, socket->GetFlags());
+ 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