Acceptor.cpp
Go to the documentation of this file.
00001 /****************************************************************************
00002 ** Copyright (c) 2001-2014
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 
00026 #include "Acceptor.h"
00027 #include "Utility.h"
00028 #include "Session.h"
00029 #include "SessionFactory.h"
00030 #include "HttpServer.h"
00031 #include <algorithm>
00032 #include <fstream>
00033 
00034 namespace FIX
00035 {
00036 Acceptor::Acceptor( Application& application,
00037                     MessageStoreFactory& messageStoreFactory,
00038                     const SessionSettings& settings )
00039 throw( ConfigError )
00040   : m_threadid( 0 ),
00041   m_application( application ),
00042   m_messageStoreFactory( messageStoreFactory ),
00043   m_settings( settings ),
00044   m_pLogFactory( 0 ),
00045   m_pLog( 0 ),
00046   m_firstPoll( true ),
00047   m_stop( true )
00048 {
00049   initialize();
00050 }
00051 
00052 Acceptor::Acceptor( Application& application,
00053                     MessageStoreFactory& messageStoreFactory,
00054                     const SessionSettings& settings,
00055                     LogFactory& logFactory )
00056 throw( ConfigError )
00057 : m_threadid( 0 ),
00058   m_application( application ),
00059   m_messageStoreFactory( messageStoreFactory ),
00060   m_settings( settings ),
00061   m_pLogFactory( &logFactory ),
00062   m_pLog( logFactory.create() ),
00063   m_firstPoll( true ),
00064   m_stop( true )
00065 {
00066   initialize();
00067 }
00068 
00069 void Acceptor::initialize() throw ( ConfigError )
00070 {
00071   std::set < SessionID > sessions = m_settings.getSessions();
00072   std::set < SessionID > ::iterator i;
00073 
00074   if ( !sessions.size() )
00075     throw ConfigError( "No sessions defined" );
00076 
00077   SessionFactory factory( m_application, m_messageStoreFactory,
00078                           m_pLogFactory );
00079 
00080   for ( i = sessions.begin(); i != sessions.end(); ++i )
00081   {
00082     if ( m_settings.get( *i ).getString( CONNECTION_TYPE ) == "acceptor" )
00083     {
00084       m_sessionIDs.insert( *i );
00085       m_sessions[ *i ] = factory.create( *i, m_settings.get( *i ) );
00086     }
00087   }
00088 
00089   if ( !m_sessions.size() )
00090     throw ConfigError( "No sessions defined for acceptor" );
00091 }
00092 
00093 Acceptor::~Acceptor()
00094 {
00095   Sessions::iterator i;
00096   for ( i = m_sessions.begin(); i != m_sessions.end(); ++i )
00097     delete i->second;
00098 
00099   if( m_pLogFactory && m_pLog )
00100     m_pLogFactory->destroy( m_pLog );
00101 }
00102 
00103 Session* Acceptor::getSession
00104 ( const std::string& msg, Responder& responder )
00105 {
00106   Message message;
00107   if ( !message.setStringHeader( msg ) )
00108     return 0;
00109 
00110   BeginString beginString;
00111   SenderCompID clSenderCompID;
00112   TargetCompID clTargetCompID;
00113   MsgType msgType;
00114   try
00115   {
00116     message.getHeader().getField( beginString );
00117     message.getHeader().getField( clSenderCompID );
00118     message.getHeader().getField( clTargetCompID );
00119     message.getHeader().getField( msgType );
00120     if ( msgType != "A" ) return 0;
00121 
00122     SenderCompID senderCompID( clTargetCompID );
00123     TargetCompID targetCompID( clSenderCompID );
00124     SessionID sessionID( beginString, senderCompID, targetCompID );
00125 
00126     Sessions::iterator i = m_sessions.find( sessionID );
00127     if ( i != m_sessions.end() )
00128     {
00129       i->second->setResponder( &responder );
00130       return i->second;
00131     }
00132   }
00133   catch ( FieldNotFound& ) {}
00134   return 0;
00135 }
00136 
00137 Session* Acceptor::getSession( const SessionID& sessionID ) const
00138 {
00139   Sessions::const_iterator i = m_sessions.find( sessionID );
00140   if( i != m_sessions.end() )
00141     return i->second;
00142   else
00143     return 0;
00144 }
00145 
00146 const Dictionary* const Acceptor::getSessionSettings( const SessionID& sessionID ) const
00147 {
00148   try
00149   {
00150     return &m_settings.get( sessionID );
00151   }
00152   catch( ConfigError& )
00153   {
00154     return 0;
00155   }
00156 }
00157 
00158 void Acceptor::start() throw ( ConfigError, RuntimeError )
00159 {
00160   m_stop = false;
00161   onConfigure( m_settings );
00162   onInitialize( m_settings );
00163 
00164   HttpServer::startGlobal( m_settings );
00165 
00166   if( !thread_spawn( &startThread, this, m_threadid ) )
00167     throw RuntimeError("Unable to spawn thread");
00168 }
00169 
00170 void Acceptor::block() throw ( ConfigError, RuntimeError )
00171 {
00172   m_stop = false;
00173   onConfigure( m_settings );
00174   onInitialize( m_settings );
00175 
00176   startThread(this);
00177 }
00178 
00179 bool Acceptor::poll( double timeout ) throw ( ConfigError, RuntimeError )
00180 {
00181   if( m_firstPoll )
00182   {
00183     m_stop = false;
00184     onConfigure( m_settings );
00185     onInitialize( m_settings );
00186     m_firstPoll = false;
00187   }
00188 
00189   return onPoll( timeout );
00190 }
00191 
00192 void Acceptor::stop( bool force )
00193 {
00194   if( isStopped() ) return;
00195 
00196   HttpServer::stopGlobal();
00197 
00198   std::vector<Session*> enabledSessions;
00199 
00200   Sessions sessions = m_sessions;
00201   Sessions::iterator i = sessions.begin();
00202   for ( ; i != sessions.end(); ++i )
00203   {
00204     Session* pSession = Session::lookupSession(i->first);
00205     if( pSession && pSession->isEnabled() )
00206     {
00207       enabledSessions.push_back( pSession );
00208       pSession->logout();
00209       Session::unregisterSession( pSession->getSessionID() );
00210     }
00211   }
00212 
00213   if( !force )
00214   {
00215     for ( int second = 1; second <= 10 && isLoggedOn(); ++second )
00216       process_sleep( 1 );
00217   }
00218 
00219   m_stop = true;
00220   onStop();
00221   if( m_threadid )
00222     thread_join( m_threadid );
00223   m_threadid = 0;
00224 
00225   std::vector<Session*>::iterator session = enabledSessions.begin();
00226   for( ; session != enabledSessions.end(); ++session )
00227     (*session)->logon();
00228 }
00229 
00230 bool Acceptor::isLoggedOn()
00231 {
00232   Sessions sessions = m_sessions;
00233   Sessions::iterator i = sessions.begin();
00234   for ( ; i != sessions.end(); ++i )
00235   {
00236     if( i->second->isLoggedOn() )
00237       return true;
00238   }
00239   return false;
00240 }
00241 
00242 THREAD_PROC Acceptor::startThread( void* p )
00243 {
00244   Acceptor * pAcceptor = static_cast < Acceptor* > ( p );
00245   pAcceptor->onStart();
00246   return 0;
00247 }
00248 }

Generated on Mon Jun 23 2014 23:49:37 for QuickFIX by doxygen 1.7.6.1 written by Dimitri van Heesch, © 1997-2001