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

HttpServer.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 "HttpServer.h"
00028 #include "HttpConnection.h"
00029 #include "Settings.h"
00030 #include "Utility.h"
00031 
00032 namespace FIX
00033 {
00034 Mutex HttpServer::s_mutex;
00035 int HttpServer::s_count = 0;
00036 HttpServer* HttpServer::s_pServer = 0;
00037 
00038 void HttpServer::startGlobal( const SessionSettings& s ) 
00039 throw ( ConfigError, RuntimeError )
00040 {
00041   Locker l( s_mutex );
00042 
00043   if( !s.get().has(HTTP_ACCEPT_PORT) )
00044     return;
00045 
00046   s_count += 1;
00047   if( !s_pServer )
00048   {
00049     s_pServer = new HttpServer( s );
00050     s_pServer->start();
00051   }
00052 }
00053 
00054 void HttpServer::stopGlobal()
00055 {
00056   Locker l( s_mutex );
00057 
00058   s_count -= 1;
00059   if( !s_count && s_pServer )
00060   {
00061     s_pServer->stop();
00062     delete s_pServer;
00063     s_pServer = 0;
00064   }  
00065 }
00066 
00067 HttpServer::HttpServer( const SessionSettings& settings ) throw( ConfigError )
00068 : m_pServer( 0 ), m_settings( settings ), m_threadid( 0 ), m_port( 0 ), m_stop( false ) {}
00069 
00070 void HttpServer::onConfigure( const SessionSettings& s )
00071 throw ( ConfigError )
00072 { QF_STACK_PUSH(HttpServer::onConfigure)
00073   m_port = s.get().getLong( HTTP_ACCEPT_PORT );
00074   QF_STACK_POP
00075 }
00076 
00077 void HttpServer::onInitialize( const SessionSettings& s )
00078 throw ( RuntimeError )
00079 { QF_STACK_PUSH(HttpServer::onInitialize)
00080 
00081   try
00082   {
00083     m_pServer = new SocketServer( 1 );
00084     m_pServer->add( m_port, true, false, 0, 0 );
00085   }
00086   catch( std::exception& )
00087   {
00088     throw RuntimeError( "Unable to create, bind, or listen to port " + IntConvertor::convert( (unsigned short)m_port ) );
00089   }
00090 
00091   QF_STACK_POP
00092 }
00093 
00094 void HttpServer::start() throw ( ConfigError, RuntimeError )
00095 { QF_STACK_PUSH( Acceptor::start )
00096 
00097   m_stop = false;
00098   onConfigure( m_settings );
00099   onInitialize( m_settings );
00100 
00101   if( !thread_spawn( &startThread, this, m_threadid ) )
00102     throw RuntimeError("Unable to spawn thread");
00103 
00104   QF_STACK_POP
00105 }
00106 
00107 void HttpServer::stop()
00108 { QF_STACK_PUSH( HttpServer::stop )
00109 
00110   if( m_stop ) return;
00111   m_stop = true;
00112   onStop();
00113 
00114   if( m_threadid )
00115     thread_join( m_threadid );
00116   m_threadid = 0;
00117 
00118   QF_STACK_POP
00119 }
00120 
00121 void HttpServer::onStart()
00122 { QF_STACK_PUSH(HttpServer::start)
00123 
00124   while ( !m_stop && m_pServer && m_pServer->block( *this ) ) {}
00125 
00126   if( !m_pServer )
00127     return;
00128 
00129   m_pServer->close();
00130   delete m_pServer;
00131   m_pServer = 0;
00132 
00133   QF_STACK_POP
00134 }
00135 
00136 bool HttpServer::onPoll()
00137 { QF_STACK_PUSH(HttpServer::onPoll)
00138 
00139   if( !m_pServer || m_stop )
00140     return false;
00141 
00142   m_pServer->block( *this, true );
00143   return true;
00144 
00145   QF_STACK_POP
00146 }
00147 
00148 void HttpServer::onStop()
00149 { QF_STACK_PUSH(HttpServer::onStop)
00150   QF_STACK_POP
00151 }
00152 
00153 void HttpServer::onConnect( SocketServer& server, int a, int s )
00154 { QF_STACK_PUSH(HttpServer::onConnect)
00155 
00156   if ( !socket_isValid( s ) ) return;
00157   HttpConnection connection( s );
00158   while( connection.read() ) {}
00159   m_pServer->getMonitor().drop( s );
00160 
00161   QF_STACK_POP
00162 }
00163 
00164 void HttpServer::onWrite( SocketServer& server, int s )
00165 { QF_STACK_PUSH(HttpServer::onWrite)
00166   QF_STACK_POP
00167 }
00168 
00169 bool HttpServer::onData( SocketServer& server, int s )
00170 { QF_STACK_PUSH(HttpServer::onData)
00171 
00172   return true;
00173 
00174   QF_STACK_POP
00175 }
00176 
00177 void HttpServer::onDisconnect( SocketServer&, int s )
00178 { QF_STACK_PUSH(HttpServer::onDisconnect)
00179   QF_STACK_POP
00180 }
00181 
00182 void HttpServer::onError( SocketServer& ) {}
00183 
00184 void HttpServer::onTimeout( SocketServer& )
00185 { QF_STACK_PUSH(HttpServer::onInitialize)
00186   QF_STACK_POP
00187 }
00188 
00189 THREAD_PROC HttpServer::startThread( void* p )
00190 { QF_STACK_TRY
00191   QF_STACK_PUSH( HttpServer::startThread )
00192 
00193   HttpServer * pServer = static_cast < HttpServer* > ( p );
00194   pServer->onStart();
00195   return 0;
00196 
00197   QF_STACK_POP
00198   QF_STACK_CATCH
00199 }
00200 
00201 }

Generated on Mon Apr 5 20:59:50 2010 for QuickFIX by doxygen 1.6.1 written by Dimitri van Heesch, © 1997-2001