Index  Source Files  Annotated Class List  Alphabetical Class List  Class Hierarchy  Graphical Class Hierarchy   
 

/home/orenmnero/autobuild/quickfix/src/C++/SocketServer.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** Copyright (c) quickfixengine.org  All rights reserved.
00003 **
00004 ** This file is part of the QuickFIX FIX Engine
00005 **
00006 ** This file may be distributed under the terms of the quickfixengine.org
00007 ** license as defined by quickfixengine.org and appearing in the file
00008 ** LICENSE included in the packaging of this file.
00009 **
00010 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00011 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00012 **
00013 ** See http://www.quickfixengine.org/LICENSE for licensing information.
00014 **
00015 ** Contact ask@quickfixengine.org if any conditions of this licensing are
00016 ** not clear to you.
00017 **
00018 ****************************************************************************/
00019 
00020 #ifdef _MSC_VER
00021 #include "stdafx.h"
00022 #else
00023 #include "config.h"
00024 #endif
00025 #include "CallStack.h"
00026 
00027 #include "SocketServer.h"
00028 #include "Utility.h"
00029 #ifndef _MSC_VER
00030 #include <unistd.h>
00031 #include <sys/ioctl.h>
00032 #include <sys/types.h>
00033 #include <sys/stat.h>
00034 #endif
00035 #include <exception>
00036 
00037 namespace FIX
00038 {
00040 class ServerWrapper : public SocketMonitor::Strategy
00041 {
00042 public:
00043   ServerWrapper( std::set<int> sockets, SocketServer& server,
00044                  SocketServer::Strategy& strategy )
00045 : m_sockets( sockets ), m_server( server ), m_strategy( strategy ) {}
00046 
00047 private:
00048   void onConnect( SocketMonitor&, int socket )
00049   { QF_STACK_PUSH(ServerWrapper::onConnect)
00050     QF_STACK_POP
00051   }
00052 
00053   void onEvent( SocketMonitor&, int socket )
00054   { QF_STACK_PUSH(ServerWrapper::onEvent)
00055 
00056     if( m_sockets.find(socket) != m_sockets.end() )
00057     {
00058       m_strategy.onConnect( m_server, socket, m_server.accept(socket) );
00059     }
00060     else
00061         m_strategy.onData( m_server, socket );
00062 
00063     QF_STACK_POP
00064   }
00065 
00066   void onWrite( SocketMonitor&, int socket )
00067   { QF_STACK_PUSH(ServerWrapper::onWrite)
00068 
00069     m_strategy.onWrite( m_server, socket );
00070 
00071     QF_STACK_POP
00072   }
00073 
00074   void onError( SocketMonitor&, int socket )
00075   { QF_STACK_PUSH(ServerWrapper::onError)
00076 
00077     m_strategy.onDisconnect( m_server, socket );
00078     m_server.getMonitor().drop( socket );
00079 
00080     QF_STACK_POP
00081   }
00082 
00083   void onError( SocketMonitor& )
00084   { QF_STACK_PUSH(ServerWrapper::onEvent)
00085     m_strategy.onError( m_server );
00086     QF_STACK_POP
00087   }
00088 
00089   void onTimeout( SocketMonitor& )
00090   { QF_STACK_PUSH(ServerWrapper::onTimeout)
00091     m_strategy.onTimeout( m_server );
00092     QF_STACK_POP
00093   };
00094 
00095   typedef std::set<int>
00096     Sockets;
00097 
00098   Sockets m_sockets;
00099   SocketServer& m_server;
00100   SocketServer::Strategy& m_strategy;
00101 };
00102 
00103 SocketServer::SocketServer( int timeout )
00104 : m_monitor( timeout ) {}
00105 
00106 int SocketServer::add( int port, bool reuse, bool noDelay )
00107 {
00108   if( m_portToInfo.find(port) != m_portToInfo.end() )
00109     return m_portToInfo[port].m_socket;
00110 
00111   int socket = socket_createAcceptor( port, reuse );
00112   if( socket < 0 )
00113     throw std::exception();
00114   if( noDelay )
00115     socket_setsockopt( socket, TCP_NODELAY );
00116   m_monitor.addRead( socket );
00117 
00118   SocketInfo info( socket, port, noDelay );
00119   m_socketToInfo[socket] = info;
00120   m_portToInfo[port] = info;
00121   return socket;
00122 }
00123 
00124 int SocketServer::accept( int socket )
00125 { QF_STACK_PUSH(SocketServer::accept)
00126 
00127   SocketInfo info = m_socketToInfo[socket];
00128 
00129   int result = socket_accept( socket );
00130   if( info.m_noDelay )
00131     socket_setsockopt( result, TCP_NODELAY );
00132   if ( result >= 0 )
00133     m_monitor.addConnect( result );
00134   return result;
00135 
00136   QF_STACK_POP
00137 }
00138 
00139 void SocketServer::close()
00140 { QF_STACK_PUSH(SocketServer::close)
00141 
00142   SocketToInfo::iterator i = m_socketToInfo.begin();
00143   for( ; i != m_socketToInfo.end(); ++i )
00144   {
00145     int s = i->first;
00146     socket_close( s );
00147     socket_invalidate( s );
00148   }
00149 
00150   QF_STACK_POP
00151 }
00152 
00153 bool SocketServer::block( Strategy& strategy, bool poll )
00154 { QF_STACK_PUSH(SocketServer::block)
00155 
00156   std::set<int> sockets;
00157   SocketToInfo::iterator i = m_socketToInfo.begin();
00158   for( ; i != m_socketToInfo.end(); ++i )
00159   {
00160     if( !socket_isValid(i->first) )
00161       return false;
00162     sockets.insert( i->first );
00163   }
00164 
00165   ServerWrapper wrapper( sockets, *this, strategy );
00166   m_monitor.block( wrapper, poll );
00167   return true;
00168 
00169   QF_STACK_POP
00170 }
00171 
00172 int SocketServer::socketToPort( int socket )
00173 {
00174   SocketToInfo::iterator find = m_socketToInfo.find( socket );
00175   if( find == m_socketToInfo.end() ) return 0;
00176   return find->second.m_port;
00177 }
00178  
00179 int SocketServer::portToSocket( int port )
00180 {
00181   SocketToInfo::iterator find = m_portToInfo.find( port );
00182   if( find == m_portToInfo.end() ) return 0;
00183   return find->second.m_socket;
00184 }
00185 }

Generated on Mon Jul 24 19:36:30 2006 for QuickFIX by doxygen 1.3.6-20040222 written by Dimitri van Heesch, © 1997-2001