$treeview $search $mathjax
AirInv Logo  1.00.0
$projectbrief
$projectbrief
$searchbox

AirInvServer_ASIO.cpp

Go to the documentation of this file.
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 }