staticlib_pion  2.0.2
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Friends Macros
tcp_server.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015, alex at staticlibs.net
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // ---------------------------------------------------------------------
18 // pion: a Boost C++ framework for building lightweight HTTP interfaces
19 // ---------------------------------------------------------------------
20 // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion)
21 //
22 // Distributed under the Boost Software License, Version 1.0.
23 // See http://www.boost.org/LICENSE_1_0.txt
24 //
25 
26 #ifndef STATICLIB_PION_TCP_SERVER_HPP
27 #define STATICLIB_PION_TCP_SERVER_HPP
28 
29 #include <condition_variable>
30 #include <mutex>
31 #include <set>
32 
33 #include "asio.hpp"
34 
35 #include "staticlib/config.hpp"
36 
39 
40 namespace staticlib {
41 namespace pion {
42 
46 class tcp_server {
47 
48 protected:
53 
57  asio::ip::tcp::acceptor tcp_acceptor;
58 
62  tcp_connection::ssl_context_type ssl_context;
63 
67  std::condition_variable server_has_stopped;
68 
72  std::condition_variable no_more_connections;
73 
77  std::set<tcp_connection_ptr> conn_pool;
78 
82  asio::ip::tcp::endpoint tcp_endpoint;
83 
87  bool ssl_flag;
88 
92  bool listening;
93 
97  mutable std::mutex mutex;
98 
99 public:
100 
106  tcp_server(const asio::ip::tcp::endpoint& endpoint, uint32_t number_of_threads) :
107  active_scheduler(number_of_threads),
109  ssl_context(asio::ssl::context::sslv23),
110  tcp_endpoint(endpoint),
111  ssl_flag(false),
112  listening(false) { }
113 
117  tcp_server(const tcp_server&) = delete;
118 
122  tcp_server& operator=(const tcp_server&) = delete;
123 
127  virtual ~tcp_server() STATICLIB_NOEXCEPT {
128  if (listening) {
129  try {
130  stop(false);
131  } catch (const std::exception& e) {
132  (void) e;
133  // STATICLIB_PION_LOG_WARN("Exception thrown in tcp::server destructor: " << e.message());
134  }
135  }
136  }
137 
141  void start();
142 
148  void stop(bool wait_until_finished = false);
149 
155  bool is_listening() const {
156  return listening;
157  }
158 
165  virtual void handle_connection(tcp_connection_ptr& tcp_conn) {
166  tcp_conn->set_lifecycle(tcp_connection::lifecycle::close); // make sure it will get closed
167  tcp_conn->finish();
168  }
169 
175  asio::io_service& get_io_service() {
177  }
178 
185  return active_scheduler;
186  }
187 
188 private:
189 
193  void handle_stop_request();
194 
198  void listen();
199 
206  void handle_accept(tcp_connection_ptr& tcp_conn, const std::error_code& accept_error);
207 
214  void handle_ssl_handshake(tcp_connection_ptr& tcp_conn, const std::error_code& handshake_error);
215 
224  void finish_connection(tcp_connection_ptr& tcp_conn);
225 
232  std::size_t prune_connections();
233 
234 };
235 
236 } // namespace
237 }
238 
239 #endif // STATICLIB_PION_TCP_SERVER_HPP