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

/home/orenmnero/autobuild/quickfix/src/C++/SocketAcceptor.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 "SocketAcceptor.h"
00028 #include "Session.h"
00029 #include "Settings.h"
00030 #include "Utility.h"
00031 
00032 namespace FIX
00033 {
00034 SocketAcceptor::SocketAcceptor( Application& application,
00035                                 MessageStoreFactory& factory,
00036                                 const SessionSettings& settings ) throw( ConfigError )
00037 : Acceptor( application, factory, settings ),
00038   m_pServer( 0 ) {}
00039 
00040 SocketAcceptor::SocketAcceptor( Application& application,
00041                                 MessageStoreFactory& factory,
00042                                 const SessionSettings& settings,
00043                                 LogFactory& logFactory ) throw( ConfigError )
00044 : Acceptor( application, factory, settings, logFactory ),
00045   m_pServer( 0 ) {}
00046 
00047 SocketAcceptor::~SocketAcceptor()
00048 {
00049   SocketConnections::iterator iter;
00050   for ( iter = m_connections.begin(); iter != m_connections.end(); ++iter )
00051     delete iter->second;
00052 }
00053 
00054 void SocketAcceptor::onConfigure( const SessionSettings& s )
00055 throw ( ConfigError )
00056 { QF_STACK_PUSH(SocketAcceptor::onConfigure)
00057 
00058   std::set<SessionID> sessions = s.getSessions();
00059   std::set<SessionID>::iterator i;
00060   for( i = sessions.begin(); i != sessions.end(); ++i )
00061   {
00062     const Dictionary& settings = s.get( *i );
00063     settings.getLong( SOCKET_ACCEPT_PORT );
00064     if( settings.has(SOCKET_REUSE_ADDRESS) )
00065       settings.getBool( SOCKET_REUSE_ADDRESS );
00066     if( settings.has(SOCKET_NODELAY) )
00067       settings.getBool( SOCKET_NODELAY );
00068   }
00069 
00070   QF_STACK_POP
00071 }
00072 
00073 void SocketAcceptor::onInitialize( const SessionSettings& s )
00074 throw ( RuntimeError )
00075 { QF_STACK_PUSH(SocketAcceptor::onInitialize)
00076 
00077   short port = 0;
00078   bool reuseAddress = false;
00079   bool noDelay = false;
00080 
00081   try
00082   {
00083     m_pServer = new SocketServer( 1 );
00084 
00085     std::set<SessionID> sessions = s.getSessions();
00086     std::set<SessionID>::iterator i = sessions.begin();
00087     for( ; i != sessions.end(); ++i )
00088     {
00089       Dictionary settings = s.get( *i );
00090       port = (short)settings.getLong( SOCKET_ACCEPT_PORT );
00091 
00092       if( settings.has( SOCKET_REUSE_ADDRESS ) )
00093         reuseAddress = s.get().getBool( SOCKET_REUSE_ADDRESS );
00094       if( settings.has( SOCKET_NODELAY ) )
00095         noDelay = s.get().getBool( SOCKET_NODELAY );
00096 
00097       m_portToSessions[port].insert( *i );
00098       m_pServer->add( port, reuseAddress, noDelay );      
00099     }    
00100   }
00101   catch( std::exception& )
00102   {
00103     throw RuntimeError( "Unable to create, bind, or listen to port " + IntConvertor::convert( (unsigned short)port ) );
00104   }
00105 
00106   QF_STACK_POP
00107 }
00108 
00109 void SocketAcceptor::onStart()
00110 { QF_STACK_PUSH(SocketAcceptor::onStart)
00111 
00112   while ( !isStopped() && m_pServer && m_pServer->block( *this ) ) {}
00113 
00114   if( !m_pServer )
00115     return;
00116 
00117   time_t start = 0;
00118   time_t now = 0;
00119 
00120   ::time( &start );
00121   while ( isLoggedOn() )
00122   {
00123     m_pServer->block( *this );
00124     if( ::time(&now) -5 >= start )
00125       break;
00126   }
00127 
00128   m_pServer->close();
00129   delete m_pServer;
00130   m_pServer = 0;
00131 
00132   QF_STACK_POP
00133 }
00134 
00135 bool SocketAcceptor::onPoll()
00136 { QF_STACK_PUSH(SocketAcceptor::onPoll)
00137 
00138   if( !m_pServer )
00139     return false;
00140 
00141   time_t start = 0;
00142   time_t now = 0;
00143 
00144   if( isStopped() )
00145   {
00146     if( start == 0 )
00147       ::time( &start );
00148     if( !isLoggedOn() )
00149       return false;
00150     if( ::time(&now) - 5 >= start )
00151       return false;
00152   }
00153 
00154   m_pServer->block( *this, true );
00155   return true;
00156 
00157   QF_STACK_POP
00158 }
00159 
00160 void SocketAcceptor::onStop()
00161 { QF_STACK_PUSH(SocketAcceptor::onStop)
00162   QF_STACK_POP
00163 }
00164 
00165 void SocketAcceptor::onConnect( SocketServer& server, int a, int s )
00166 { QF_STACK_PUSH(SocketAcceptor::onConnect)
00167 
00168   if ( !socket_isValid( s ) ) return;
00169   SocketConnections::iterator i = m_connections.find( s );
00170   if ( i != m_connections.end() ) return;
00171   int port = server.socketToPort( a );
00172   Sessions sessions = m_portToSessions[port];
00173   m_connections[ s ] = new SocketConnection( s, sessions, &server.getMonitor() );
00174 
00175   std::stringstream stream;
00176   stream << "Accepted connection from " << socket_peername( s ) << " on port " << port;
00177   log( stream.str() );
00178 
00179   QF_STACK_POP
00180 }
00181 
00182 void SocketAcceptor::onWrite( SocketServer& server, int s )
00183 { QF_STACK_PUSH(SocketAcceptor::onWrite)
00184 
00185   SocketConnections::iterator i = m_connections.find( s );
00186   if ( i == m_connections.end() ) return ;
00187   SocketConnection* pSocketConnection = i->second;
00188   if( pSocketConnection->processQueue() )
00189     pSocketConnection->unsignal();
00190 
00191   QF_STACK_POP
00192 }
00193 
00194 void SocketAcceptor::onData( SocketServer& server, int s )
00195 { QF_STACK_PUSH(SocketAcceptor::onData)
00196 
00197   SocketConnections::iterator i = m_connections.find( s );
00198   if ( i == m_connections.end() ) return ;
00199   SocketConnection* pSocketConnection = i->second;
00200   pSocketConnection->read( *this, server );
00201 
00202   QF_STACK_POP
00203 }
00204 
00205 void SocketAcceptor::onDisconnect( SocketServer&, int s )
00206 { QF_STACK_PUSH(SocketAcceptor::onDisconnect)
00207 
00208   SocketConnections::iterator i = m_connections.find( s );
00209   if ( i == m_connections.end() ) return ;
00210   SocketConnection* pSocketConnection = i->second;
00211 
00212   Session* pSession = pSocketConnection->getSession();
00213   if ( pSession ) pSession->disconnect();
00214 
00215   delete pSocketConnection;
00216   m_connections.erase( s );
00217 
00218   QF_STACK_POP
00219 }
00220 
00221 void SocketAcceptor::onError( SocketServer& ) {}
00222 
00223 void SocketAcceptor::onTimeout( SocketServer& )
00224 { QF_STACK_PUSH(SocketAcceptor::onInitialize)
00225 
00226   SocketConnections::iterator i;
00227   for ( i = m_connections.begin(); i != m_connections.end(); ++i )
00228     i->second->onTimeout();
00229 
00230   QF_STACK_POP
00231 }
00232 }

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