Kea 2.5.8
mt_tcp_listener_mgr.cc
Go to the documentation of this file.
1// Copyright (C) 2022-2024 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
10#include <asiolink/io_error.h>
11#include <asiolink/io_service.h>
12#include <mt_tcp_listener_mgr.h>
13#include <tcp_log.h>
15
16#include <boost/pointer_cast.hpp>
17
18using namespace isc::asiolink;
19using namespace isc::tcp;
20using namespace isc::util;
21
22namespace isc {
23namespace tcp {
24
26 const IOAddress& address,
27 const uint16_t port,
28 const uint16_t thread_pool_size /* = 1 */,
29 TlsContextPtr context /* = () */,
30 TcpConnectionFilterCallback connection_filter /* = 0 */)
31 : listener_factory_(listener_factory), address_(address), port_(port),
32 thread_io_service_(), tcp_listener_(), thread_pool_size_(thread_pool_size),
33 thread_pool_(), tls_context_(context), connection_filter_(connection_filter),
34 idle_timeout_(TCP_IDLE_CONNECTION_TIMEOUT) {
35}
36
38 stop();
39}
40
41void
43 // We must be in multi-threading mode.
44 if (!MultiThreadingMgr::instance().getMode()) {
45 isc_throw(InvalidOperation, "MtTcpListenerMgr cannot be started"
46 " when multi-threading is disabled");
47 }
48
49 // Punt if we're already started.
50 if (!isStopped()) {
51 isc_throw(InvalidOperation, "MtTcpListenerMgr already started!");
52 }
53
54 try {
55 // Create a new IOService.
56 thread_io_service_.reset(new IOService());
57
58 // Create a new TCPListener derivation using the factory.
59 tcp_listener_ = listener_factory_(thread_io_service_,
60 address_,
61 port_,
62 tls_context_,
63 idle_timeout_,
64 connection_filter_);
65
66 // Instruct the HTTP listener to actually open socket, install
67 // callback and start listening.
68 tcp_listener_->start();
69
70 // Create the thread pool with immediate start.
71 thread_pool_.reset(new IoServiceThreadPool(thread_io_service_, thread_pool_size_));
72
73 // OK, seems like we're good to go.
75 .arg(thread_pool_size_)
76 .arg(address_)
77 .arg(port_)
78 .arg(tls_context_ ? "true" : "false");
79 } catch (const std::exception& ex) {
80 if (thread_pool_) {
81 // Stop the thread pool.
82 thread_pool_->stop();
83 }
84
85 if (tcp_listener_) {
86 // Stop the listener.
87 tcp_listener_->stop();
88 }
89
90 if (thread_io_service_) {
91 thread_io_service_->stop();
92 thread_io_service_->restart();
93 try {
94 thread_io_service_->poll();
95 } catch (...) {
96 }
97 thread_io_service_->stop();
98 }
99
100 // Get rid of the thread pool.
101 thread_pool_.reset();
102
103 // Get rid of the listener.
104 tcp_listener_.reset();
105
106 // Ditch the IOService.
107 thread_io_service_.reset();
108
109 isc_throw(Unexpected, "MtTcpListenerMgr::start failed:" << ex.what());
110 }
111}
112
113void
115 if (thread_pool_) {
116 thread_pool_->checkPausePermissions();
117 }
118}
119
120void
122 if (thread_pool_) {
123 thread_pool_->pause();
124 }
125}
126
127void
129 if (thread_pool_) {
130 thread_pool_->run();
131 }
132}
133
134void
136 // Nothing to do.
137 if (!thread_io_service_) {
138 return;
139 }
140
142 .arg(address_)
143 .arg(port_);
144
145 // Stop the thread pool.
146 thread_pool_->stop();
147
148 // Stop the listener.
149 tcp_listener_->stop();
150
151 thread_io_service_->stop();
152 thread_io_service_->restart();
153 try {
154 thread_io_service_->poll();
155 } catch (...) {
156 }
157 thread_io_service_->stop();
158
159 // Get rid of the thread pool.
160 thread_pool_.reset();
161
162 // Get rid of the listener.
163 tcp_listener_.reset();
164
165 // Ditch the IOService.
166 thread_io_service_.reset();
167
169 .arg(address_)
170 .arg(port_);
171}
172
173bool
175 if (thread_pool_) {
176 return (thread_pool_->isRunning());
177 }
178
179 return (false);
180}
181
182bool
184 if (thread_pool_) {
185 return (thread_pool_->isStopped());
186 }
187
188 return (true);
189}
190
191bool
193 if (thread_pool_) {
194 return (thread_pool_->isPaused());
195 }
196
197 return (false);
198}
199
200} // namespace isc::config
201} // namespace isc
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a function is called in a prohibited way.
A generic exception that is thrown when an unexpected error condition occurs.
void pause()
Pauses the listener's thread pool.
void start()
Starts running the listener's thread pool.
bool isPaused()
Indicates if the thread pool is paused.
void checkPermissions()
Check if the current thread can perform thread pool state transition.
bool isStopped()
Indicates if the thread pool is stopped.
MtTcpListenerMgr(TcpListenerFactory listener_factory, const asiolink::IOAddress &address, const uint16_t port, const uint16_t thread_pool_size=1, asiolink::TlsContextPtr context=asiolink::TlsContextPtr(), TcpConnectionFilterCallback connection_filter=0)
Constructor.
void resume()
Resumes running the listener's thread pool.
void stop()
Stops the listener's thread pool.
virtual ~MtTcpListenerMgr()
Destructor.
bool isRunning()
Indicates if the thread pool is running.
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
const int DBGLVL_TRACE_BASIC
Trace basic operations.
Definition: log_dbglevels.h:69
std::function< bool(const boost::asio::ip::tcp::endpoint &)> TcpConnectionFilterCallback
Type of the callback for filtering new connections by ip address.
const long TCP_IDLE_CONNECTION_TIMEOUT
Default connection idle timeout in milliseconds.
std::function< TcpListenerPtr(const asiolink::IOServicePtr &io_service, const asiolink::IOAddress &server_address, const unsigned short server_port, const asiolink::TlsContextPtr &tls_context, const TcpListener::IdleTimeout &idle_timeout, const TcpConnectionFilterCallback &connection_filter) > TcpListenerFactory
Defines a factory function for creating TcpListeners.
const isc::log::MessageID MT_TCP_LISTENER_MGR_STARTED
Definition: tcp_messages.h:11
const isc::log::MessageID MT_TCP_LISTENER_MGR_STOPPING
Definition: tcp_messages.h:13
isc::log::Logger tcp_logger("tcp")
Defines the logger used within libkea-tcp library.
Definition: tcp_log.h:18
const isc::log::MessageID MT_TCP_LISTENER_MGR_STOPPED
Definition: tcp_messages.h:12
Defines the logger used by the top-level component of kea-lfc.