| Kea 3.0.2-git

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>
8#include <asiolink/asio_wrapper.h>
9#include <asiolink/io_address.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>
14#include <util/multi_threading_mgr.h>
15
16#include <boost/pointer_cast.hpp>
17
18 using namespace isc::asiolink;
19 using namespace isc::tcp;
20 using namespace isc::util;
21
22 namespace isc {
23 namespace tcp {
24
25 MtTcpListenerMgr::MtTcpListenerMgr(TcpListenerFactory listener_factory,
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
37 MtTcpListenerMgr::~MtTcpListenerMgr() {
38 stop();
39}
40
41 void
42 MtTcpListenerMgr::start() {
43 if (MultiThreadingMgr::instance().isTestMode()) {
44 return;
45 }
46 // We must be in multi-threading mode.
47 if (!MultiThreadingMgr::instance().getMode()) {
48 isc_throw(InvalidOperation, "MtTcpListenerMgr cannot be started"
49 " when multi-threading is disabled");
50 }
51
52 // Punt if we're already started.
53 if (!isStopped()) {
54 isc_throw(InvalidOperation, "MtTcpListenerMgr already started!");
55 }
56
57 try {
58 // Create a new IOService.
59 thread_io_service_.reset(new IOService());
60
61 // Create a new TCPListener derivation using the factory.
62 tcp_listener_ = listener_factory_(thread_io_service_,
63 address_,
64 port_,
65 tls_context_,
66 idle_timeout_,
67 connection_filter_);
68
69 // Instruct the HTTP listener to actually open socket, install
70 // callback and start listening.
71 tcp_listener_->start();
72
73 // Create the thread pool with immediate start.
74 thread_pool_.reset(new IoServiceThreadPool(thread_io_service_, thread_pool_size_));
75
76 // OK, seems like we're good to go.
77 LOG_DEBUG(tcp_logger, isc::log::DBGLVL_TRACE_BASIC, MT_TCP_LISTENER_MGR_STARTED)
78 .arg(thread_pool_size_)
79 .arg(address_)
80 .arg(port_)
81 .arg(tls_context_ ? "true" : "false");
82 } catch (const std::exception& ex) {
83 if (thread_pool_) {
84 // Stop the thread pool.
85 thread_pool_->stop();
86 }
87
88 if (tcp_listener_) {
89 // Stop the listener.
90 tcp_listener_->stop();
91 }
92
93 if (thread_io_service_) {
94 thread_io_service_->stopAndPoll();
95 thread_io_service_->stop();
96 }
97
98 // Get rid of the thread pool.
99 thread_pool_.reset();
100
101 // Get rid of the listener.
102 tcp_listener_.reset();
103
104 // Ditch the IOService.
105 thread_io_service_.reset();
106
107 isc_throw(Unexpected, "MtTcpListenerMgr::start failed:" << ex.what());
108 }
109}
110
111 void
112 MtTcpListenerMgr::checkPermissions() {
113 if (thread_pool_) {
114 thread_pool_->checkPausePermissions();
115 }
116}
117
118 void
119 MtTcpListenerMgr::pause() {
120 if (thread_pool_) {
121 thread_pool_->pause();
122 }
123}
124
125 void
126 MtTcpListenerMgr::resume() {
127 if (thread_pool_) {
128 thread_pool_->run();
129 }
130}
131
132 void
133 MtTcpListenerMgr::stop() {
134 // Nothing to do.
135 if (!thread_io_service_) {
136 return;
137 }
138
139 LOG_DEBUG(tcp_logger, isc::log::DBGLVL_TRACE_BASIC, MT_TCP_LISTENER_MGR_STOPPING)
140 .arg(address_)
141 .arg(port_);
142
143 // Stop the thread pool.
144 thread_pool_->stop();
145
146 // Stop the listener.
147 tcp_listener_->stop();
148
149 thread_io_service_->stopAndPoll();
150 thread_io_service_->stop();
151
152 // Get rid of the thread pool.
153 thread_pool_.reset();
154
155 // Get rid of the listener.
156 tcp_listener_.reset();
157
158 // Ditch the IOService.
159 thread_io_service_.reset();
160
161 LOG_DEBUG(tcp_logger, isc::log::DBGLVL_TRACE_BASIC, MT_TCP_LISTENER_MGR_STOPPED)
162 .arg(address_)
163 .arg(port_);
164}
165
166 bool
167 MtTcpListenerMgr::isRunning() {
168 if (thread_pool_) {
169 return (thread_pool_->isRunning());
170 }
171
172 return (false);
173}
174
175 bool
176 MtTcpListenerMgr::isStopped() {
177 if (thread_pool_) {
178 return (thread_pool_->isStopped());
179 }
180
181 return (true);
182}
183
184 bool
185 MtTcpListenerMgr::isPaused() {
186 if (thread_pool_) {
187 return (thread_pool_->isPaused());
188 }
189
190 return (false);
191}
192
193} // namespace isc::config
194} // namespace isc
asio_wrapper.h
isc::InvalidOperation
A generic exception that is thrown if a function is called in a prohibited way.
Definition exceptions/exceptions.h:143
isc::Unexpected
A generic exception that is thrown when an unexpected error condition occurs.
Definition exceptions/exceptions.h:153
isc::asiolink::IOAddress
The IOAddress class represents an IP addresses (version agnostic).
Definition io_address.h:45
isc::asiolink::IOService
The IOService class is a wrapper for the ASIO io_context class.
Definition io_service.h:32
isc::asiolink::IoServiceThreadPool
Implements a pausable pool of IOService driven threads.
Definition io_service_thread_pool.h:24
isc::tcp::MtTcpListenerMgr::pause
void pause()
Pauses the listener's thread pool.
Definition mt_tcp_listener_mgr.cc:119
isc::tcp::MtTcpListenerMgr::start
void start()
Starts running the listener's thread pool.
Definition mt_tcp_listener_mgr.cc:42
isc::tcp::MtTcpListenerMgr::isPaused
bool isPaused()
Indicates if the thread pool is paused.
Definition mt_tcp_listener_mgr.cc:185
isc::tcp::MtTcpListenerMgr::checkPermissions
void checkPermissions()
Check if the current thread can perform thread pool state transition.
Definition mt_tcp_listener_mgr.cc:112
isc::tcp::MtTcpListenerMgr::isStopped
bool isStopped()
Indicates if the thread pool is stopped.
Definition mt_tcp_listener_mgr.cc:176
isc::tcp::MtTcpListenerMgr::MtTcpListenerMgr
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.
Definition mt_tcp_listener_mgr.cc:25
isc::tcp::MtTcpListenerMgr::resume
void resume()
Resumes running the listener's thread pool.
Definition mt_tcp_listener_mgr.cc:126
isc::tcp::MtTcpListenerMgr::stop
void stop()
Stops the listener's thread pool.
Definition mt_tcp_listener_mgr.cc:133
isc::tcp::MtTcpListenerMgr::~MtTcpListenerMgr
virtual ~MtTcpListenerMgr()
Destructor.
Definition mt_tcp_listener_mgr.cc:37
isc::tcp::MtTcpListenerMgr::isRunning
bool isRunning()
Indicates if the thread pool is running.
Definition mt_tcp_listener_mgr.cc:167
isc::util::MultiThreadingMgr::instance
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
Definition multi_threading_mgr.cc:25
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
io_address.h
io_error.h
io_service.h
LOG_DEBUG
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition macros.h:14
mt_tcp_listener_mgr.h
multi_threading_mgr.h
isc::asiolink
Definition addr_utilities.cc:170
isc::asiolink::TlsContextPtr
boost::shared_ptr< TlsContext > TlsContextPtr
The type of shared pointers to TlsContext objects.
Definition common_tls.h:37
isc::log::DBGLVL_TRACE_BASIC
const int DBGLVL_TRACE_BASIC
Trace basic operations.
Definition log_dbglevels.h:69
isc::tcp
Definition mt_tcp_listener_mgr.cc:23
isc::tcp::TcpConnectionFilterCallback
std::function< bool(const boost::asio::ip::tcp::endpoint &)> TcpConnectionFilterCallback
Type of the callback for filtering new connections by ip address.
Definition tcp_connection.h:154
isc::tcp::TCP_IDLE_CONNECTION_TIMEOUT
const long TCP_IDLE_CONNECTION_TIMEOUT
Default connection idle timeout in milliseconds.
Definition mt_tcp_listener_mgr.h:21
isc::tcp::TcpListenerFactory
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.
Definition mt_tcp_listener_mgr.h:31
isc::tcp::MT_TCP_LISTENER_MGR_STARTED
const isc::log::MessageID MT_TCP_LISTENER_MGR_STARTED
Definition tcp_messages.h:11
isc::tcp::MT_TCP_LISTENER_MGR_STOPPING
const isc::log::MessageID MT_TCP_LISTENER_MGR_STOPPING
Definition tcp_messages.h:13
isc::tcp::tcp_logger
isc::log::Logger tcp_logger("tcp")
Defines the logger used within libkea-tcp library.
Definition tcp_log.h:18
isc::tcp::MT_TCP_LISTENER_MGR_STOPPED
const isc::log::MessageID MT_TCP_LISTENER_MGR_STOPPED
Definition tcp_messages.h:12
isc::util
Definition time_utils.cc:43
isc
Defines the logger used by the top-level component of kea-lfc.
Definition agent_parser.cc:148
tcp_log.h