AirInv Logo  1.00.0
C++ Simulated Airline Inventory Management System library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AirInvServer_ASIO.cpp
Go to the documentation of this file.
1 // //////////////////////////////////////////////////////////////////////
2 // Import section
3 // //////////////////////////////////////////////////////////////////////
4 // STL
5 #include <cassert>
6 // Boost
7 #include <boost/thread.hpp>
8 #include <boost/bind.hpp>
9 // AirInv
11 
12 namespace AIRINV {
13 
14  // Type definitions
15  typedef boost::shared_ptr<boost::thread> ThreadShrPtr_T;
16  typedef std::vector<ThreadShrPtr_T> ThreadShrPtrList_T;
17 
18 
19  // //////////////////////////////////////////////////////////////////////
20  AirInvServer::AirInvServer (const std::string& address,
21  const std::string& port,
22  const stdair::AirlineCode_T& iAirlineCode,
23  std::size_t iThreadPoolSize)
24  : _threadPoolSize (iThreadPoolSize), _acceptor (_ioService),
25  _newConnection (new Connection (_ioService, _requestHandler)),
26  _requestHandler (iAirlineCode) {
27 
28  // Open the acceptor with the option to reuse the address
29  // (i.e. SO_REUSEADDR).
30  boost::asio::ip::tcp::resolver resolver (_ioService);
31  boost::asio::ip::tcp::resolver::query query (address, port);
32  boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
33 
34  _acceptor.open (endpoint.protocol());
35  _acceptor.set_option (boost::asio::ip::tcp::acceptor::reuse_address(true));
36  _acceptor.bind (endpoint);
37  _acceptor.listen();
38 
39  assert (_newConnection != NULL);
40  _acceptor.async_accept (_newConnection->socket(),
41  boost::bind (&AirInvServer::handleAccept, this,
42  boost::asio::placeholders::error));
43  }
44 
45  // //////////////////////////////////////////////////////////////////////
47  }
48 
49  // //////////////////////////////////////////////////////////////////////
51  // Create a pool of threads to run all of the io_services.
52  ThreadShrPtrList_T lThreadList;
53 
54  for (std::size_t itThread = 0; itThread != _threadPoolSize; ++itThread) {
55  ThreadShrPtr_T lThread (new boost::thread (boost::bind (&boost::asio::io_service::run,
56  &_ioService)));
57  lThreadList.push_back (lThread);
58  }
59 
60  // Wait for all threads in the pool to exit.
61  for (std::size_t itThread = 0; itThread != lThreadList.size(); ++itThread) {
62  boost::shared_ptr<boost::thread> lThread_ptr = lThreadList.at (itThread);
63  assert (lThread_ptr != NULL);
64  lThread_ptr->join();
65  }
66  }
67 
68  // //////////////////////////////////////////////////////////////////////
70  _ioService.stop();
71  }
72 
73  // //////////////////////////////////////////////////////////////////////
74  void AirInvServer::handleAccept (const boost::system::error_code& iError) {
75 
76  if (!iError) {
77 
78  assert (_newConnection != NULL);
79 
80  // The Connection object now takes in charge reading an incoming
81  // message from the socket, and writing back a message.
82  _newConnection->start();
83 
84  // The (Boost) shared pointer is resetted to a newly allocated Connection
85  // object. As the older Connection object is no longer pointed to, it is
86  // deleted by the shared pointer mechanism.
87  _newConnection.reset (new Connection (_ioService, _requestHandler));
88 
89  _acceptor.async_accept (_newConnection->socket(),
90  boost::bind (&AirInvServer::handleAccept, this,
91  boost::asio::placeholders::error));
92  }
93  }
94 
95 }