$treeview $search $mathjax
00001 // ////////////////////////////////////////////////////////////////////// 00002 // Import section 00003 // ////////////////////////////////////////////////////////////////////// 00004 // STL 00005 #include <cassert> 00006 // Boost 00007 #include <boost/thread.hpp> 00008 #include <boost/bind.hpp> 00009 // AirInv 00010 #include <airinv/server/AirInvServer.hpp> 00011 00012 namespace AIRINV { 00013 00014 // Type definitions 00015 typedef boost::shared_ptr<boost::thread> ThreadShrPtr_T; 00016 typedef std::vector<ThreadShrPtr_T> ThreadShrPtrList_T; 00017 00018 00019 // ////////////////////////////////////////////////////////////////////// 00020 AirInvServer::AirInvServer (const std::string& address, 00021 const std::string& port, 00022 const stdair::AirlineCode_T& iAirlineCode, 00023 std::size_t iThreadPoolSize) 00024 : _threadPoolSize (iThreadPoolSize), _acceptor (_ioService), 00025 _newConnection (new Connection (_ioService, _requestHandler)), 00026 _requestHandler (iAirlineCode) { 00027 00028 // Open the acceptor with the option to reuse the address 00029 // (i.e. SO_REUSEADDR). 00030 boost::asio::ip::tcp::resolver resolver (_ioService); 00031 boost::asio::ip::tcp::resolver::query query (address, port); 00032 boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query); 00033 00034 _acceptor.open (endpoint.protocol()); 00035 _acceptor.set_option (boost::asio::ip::tcp::acceptor::reuse_address(true)); 00036 _acceptor.bind (endpoint); 00037 _acceptor.listen(); 00038 00039 assert (_newConnection != NULL); 00040 _acceptor.async_accept (_newConnection->socket(), 00041 boost::bind (&AirInvServer::handleAccept, this, 00042 boost::asio::placeholders::error)); 00043 } 00044 00045 // ////////////////////////////////////////////////////////////////////// 00046 AirInvServer::~AirInvServer () { 00047 } 00048 00049 // ////////////////////////////////////////////////////////////////////// 00050 void AirInvServer::run() { 00051 // Create a pool of threads to run all of the io_services. 00052 ThreadShrPtrList_T lThreadList; 00053 00054 for (std::size_t itThread = 0; itThread != _threadPoolSize; ++itThread) { 00055 ThreadShrPtr_T lThread (new boost::thread (boost::bind (&boost::asio::io_service::run, 00056 &_ioService))); 00057 lThreadList.push_back (lThread); 00058 } 00059 00060 // Wait for all threads in the pool to exit. 00061 for (std::size_t itThread = 0; itThread != lThreadList.size(); ++itThread) { 00062 boost::shared_ptr<boost::thread> lThread_ptr = lThreadList.at (itThread); 00063 assert (lThread_ptr != NULL); 00064 lThread_ptr->join(); 00065 } 00066 } 00067 00068 // ////////////////////////////////////////////////////////////////////// 00069 void AirInvServer::stop() { 00070 _ioService.stop(); 00071 } 00072 00073 // ////////////////////////////////////////////////////////////////////// 00074 void AirInvServer::handleAccept (const boost::system::error_code& iError) { 00075 00076 if (!iError) { 00077 00078 assert (_newConnection != NULL); 00079 00080 // The Connection object now takes in charge reading an incoming 00081 // message from the socket, and writing back a message. 00082 _newConnection->start(); 00083 00084 // The (Boost) shared pointer is resetted to a newly allocated Connection 00085 // object. As the older Connection object is no longer pointed to, it is 00086 // deleted by the shared pointer mechanism. 00087 _newConnection.reset (new Connection (_ioService, _requestHandler)); 00088 00089 _acceptor.async_accept (_newConnection->socket(), 00090 boost::bind (&AirInvServer::handleAccept, this, 00091 boost::asio::placeholders::error)); 00092 } 00093 } 00094 00095 }