From: Razvan Becheriu Date: Thu, 23 Mar 2023 18:48:48 +0000 (+0200) Subject: [#2799] fixed crash on Listener stop if start throws X-Git-Tag: Kea-2.3.6~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e101a5cb2cfd4f1064c96d9e757e2eb13791fa45;p=thirdparty%2Fkea.git [#2799] fixed crash on Listener stop if start throws --- diff --git a/src/bin/dhcp4/ctrl_dhcp4_srv.cc b/src/bin/dhcp4/ctrl_dhcp4_srv.cc index 66a369b118..436f2d982a 100644 --- a/src/bin/dhcp4/ctrl_dhcp4_srv.cc +++ b/src/bin/dhcp4/ctrl_dhcp4_srv.cc @@ -239,7 +239,12 @@ ControlledDhcpv4Srv::commandLibReloadHandler(const string&, ConstElementPtr) { HookLibsCollection loaded = HooksManager::getLibraryInfo(); HooksManager::prepareUnloadLibraries(); static_cast(HooksManager::unloadLibraries()); - bool status = HooksManager::loadLibraries(loaded); + bool multi_threading_enabled = true; + uint32_t thread_count = 0; + uint32_t queue_size = 0; + CfgMultiThreading::extract(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading(), + multi_threading_enabled, thread_count, queue_size); + bool status = HooksManager::loadLibraries(loaded, multi_threading_enabled); if (!status) { isc_throw(Unexpected, "Failed to reload hooks libraries " "(WARNING: libreload is deprecated)."); @@ -259,7 +264,7 @@ ConstElementPtr ControlledDhcpv4Srv::commandConfigReloadHandler(const string&, ConstElementPtr /*args*/) { // Get configuration file name. - std::string file = ControlledDhcpv4Srv::getInstance()->getConfigFile(); + string file = ControlledDhcpv4Srv::getInstance()->getConfigFile(); try { LOG_INFO(dhcp4_logger, DHCP4_DYNAMIC_RECONFIGURATION).arg(file); auto result = loadConfigFile(file); @@ -320,7 +325,7 @@ ControlledDhcpv4Srv::commandConfigWriteHandler(const string&, ConstElementPtr cfg = CfgMgr::instance().getCurrentCfg()->toElement(); size = writeConfigFile(filename, cfg); } catch (const isc::Exception& ex) { - return (createAnswer(CONTROL_RESULT_ERROR, string("Error during write-config:") + return (createAnswer(CONTROL_RESULT_ERROR, string("Error during write-config: ") + ex.what())); } if (size == 0) { diff --git a/src/bin/dhcp4/ctrl_dhcp4_srv.h b/src/bin/dhcp4/ctrl_dhcp4_srv.h index 83b339f73e..99f668c4c6 100644 --- a/src/bin/dhcp4/ctrl_dhcp4_srv.h +++ b/src/bin/dhcp4/ctrl_dhcp4_srv.h @@ -45,18 +45,18 @@ public: /// @brief Configure DHCPv4 server using the configuration file specified. /// - /// This utility method is called whenever we know a filename of the config - /// and need to load it. It calls config-set command once the content of - /// the file has been loaded and verified to be a sane JSON configuration. - /// config-set handler will process the config file (load it as current - /// configuration). - /// /// This function is used to both configure the DHCP server on its startup /// and dynamically reconfigure the server when SIGHUP signal is received. /// /// It fetches DHCPv4 server's configuration from the 'Dhcp4' section of /// the JSON configuration file. /// + /// This utility method is called whenever we know a filename of the config + /// and need to load it. It calls config-set command once the content of + /// the file has been loaded and verified to be a sane JSON configuration. + /// config-set handler will process the config file (apply it as current + /// configuration). + /// /// @param file_name name of the file to be loaded /// @return status of the file loading and outcome of config-set isc::data::ConstElementPtr @@ -70,7 +70,7 @@ public: /// @brief Initiates shutdown procedure for the whole DHCPv4 server. /// @param exit_value integer value to the process should exit with. - void shutdownServer(int exit_value); + virtual void shutdownServer(int exit_value); /// @brief Command processor /// @@ -80,11 +80,18 @@ public: /// in them. /// /// Currently supported commands are: - /// - config-reload - /// - config-test /// - shutdown /// - libreload + /// - config-reload + /// - config-set + /// - config-get + /// - config-test + /// - dhcp-disable + /// - dhcp-enable + /// - version-get + /// - build-report /// - leases-reclaim + /// - config-write /// ... /// /// @note It never throws. @@ -140,7 +147,6 @@ public: } private: - /// @brief Callback that will be called from iface_mgr when data /// is received over control socket. /// diff --git a/src/bin/dhcp6/ctrl_dhcp6_srv.cc b/src/bin/dhcp6/ctrl_dhcp6_srv.cc index 55c3046dbf..b4d9e0d2ed 100644 --- a/src/bin/dhcp6/ctrl_dhcp6_srv.cc +++ b/src/bin/dhcp6/ctrl_dhcp6_srv.cc @@ -19,8 +19,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -91,6 +91,41 @@ namespace dhcp { ControlledDhcpv6Srv* ControlledDhcpv6Srv::server_ = NULL; +void +ControlledDhcpv6Srv::init(const std::string& file_name) { + // Keep the call timestamp. + start_ = boost::posix_time::second_clock::universal_time(); + + // Configure the server using JSON file. + ConstElementPtr result = loadConfigFile(file_name); + + int rcode; + ConstElementPtr comment = isc::config::parseAnswer(rcode, result); + if (rcode != CONTROL_RESULT_SUCCESS) { + string reason = comment ? comment->stringValue() : + "no details available"; + isc_throw(isc::BadValue, reason); + } + + // We don't need to call openActiveSockets() or startD2() as these + // methods are called in processConfig() which is called by + // processCommand("config-set", ...) + + // Set signal handlers. When the SIGHUP is received by the process + // the server reconfiguration will be triggered. When SIGTERM or + // SIGINT will be received, the server will start shutting down. + signal_set_.reset(new IOSignalSet(getIOService(), signalHandler)); + + signal_set_->add(SIGINT); + signal_set_->add(SIGHUP); + signal_set_->add(SIGTERM); +} + +void ControlledDhcpv6Srv::cleanup() { + signal_set_.reset(); + getIOService()->poll(); +} + ConstElementPtr ControlledDhcpv6Srv::loadConfigFile(const std::string& file_name) { // This is a configuration backend implementation that reads the @@ -103,8 +138,8 @@ ControlledDhcpv6Srv::loadConfigFile(const std::string& file_name) { try { if (file_name.empty()) { // Basic sanity check: file name must not be empty. - isc_throw(isc::BadValue, "JSON configuration file not specified. Please " - "use -c command line option."); + isc_throw(isc::BadValue, "JSON configuration file not specified." + " Please use -c command line option."); } // Read contents of the file and parse it as JSON @@ -163,41 +198,6 @@ ControlledDhcpv6Srv::loadConfigFile(const std::string& file_name) { return (result); } -void -ControlledDhcpv6Srv::init(const std::string& file_name) { - // Keep the call timestamp. - start_ = boost::posix_time::second_clock::universal_time(); - - // Configure the server using JSON file. - ConstElementPtr result = loadConfigFile(file_name); - - int rcode; - ConstElementPtr comment = isc::config::parseAnswer(rcode, result); - if (rcode != CONTROL_RESULT_SUCCESS) { - string reason = comment ? comment->stringValue() : - "no details available"; - isc_throw(isc::BadValue, reason); - } - - // We don't need to call openActiveSockets() or startD2() as these - // methods are called in processConfig() which is called by - // processCommand("config-set", ...) - - // Set signal handlers. When the SIGHUP is received by the process - // the server reconfiguration will be triggered. When SIGTERM or - // SIGINT will be received, the server will start shutting down. - signal_set_.reset(new IOSignalSet(getIOService(), signalHandler)); - - signal_set_->add(SIGINT); - signal_set_->add(SIGHUP); - signal_set_->add(SIGTERM); -} - -void ControlledDhcpv6Srv::cleanup() { - signal_set_.reset(); - getIOService()->poll(); -} - ConstElementPtr ControlledDhcpv6Srv::commandShutdownHandler(const string&, ConstElementPtr args) { if (!ControlledDhcpv6Srv::getInstance()) { @@ -242,10 +242,15 @@ ControlledDhcpv6Srv::commandLibReloadHandler(const string&, ConstElementPtr) { HookLibsCollection loaded = HooksManager::getLibraryInfo(); HooksManager::prepareUnloadLibraries(); static_cast(HooksManager::unloadLibraries()); - bool status = HooksManager::loadLibraries(loaded); + bool multi_threading_enabled = true; + uint32_t thread_count = 0; + uint32_t queue_size = 0; + CfgMultiThreading::extract(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading(), + multi_threading_enabled, thread_count, queue_size); + bool status = HooksManager::loadLibraries(loaded, multi_threading_enabled); if (!status) { - isc_throw(Unexpected, "Failed to reload hooks libraries" - " (WARNING: libreload is deprecated)."); + isc_throw(Unexpected, "Failed to reload hooks libraries " + "(WARNING: libreload is deprecated)."); } } catch (const std::exception& ex) { LOG_ERROR(dhcp6_logger, DHCP6_HOOKS_LIBS_RELOAD_FAIL); @@ -262,7 +267,7 @@ ConstElementPtr ControlledDhcpv6Srv::commandConfigReloadHandler(const string&, ConstElementPtr /*args*/) { // Get configuration file name. - std::string file = ControlledDhcpv6Srv::getInstance()->getConfigFile(); + string file = ControlledDhcpv6Srv::getInstance()->getConfigFile(); try { LOG_INFO(dhcp6_logger, DHCP6_DYNAMIC_RECONFIGURATION).arg(file); auto result = loadConfigFile(file); @@ -323,7 +328,7 @@ ControlledDhcpv6Srv::commandConfigWriteHandler(const string&, ConstElementPtr cfg = CfgMgr::instance().getCurrentCfg()->toElement(); size = writeConfigFile(filename, cfg); } catch (const isc::Exception& ex) { - return (createAnswer(CONTROL_RESULT_ERROR, string("Error during write-config:") + return (createAnswer(CONTROL_RESULT_ERROR, string("Error during write-config: ") + ex.what())); } if (size == 0) { @@ -1115,8 +1120,8 @@ ControlledDhcpv6Srv::checkConfig(isc::data::ConstElementPtr config) { return (configureDhcp6Server(*srv, config, true)); } -ControlledDhcpv6Srv::ControlledDhcpv6Srv(uint16_t server_port, - uint16_t client_port) +ControlledDhcpv6Srv::ControlledDhcpv6Srv(uint16_t server_port /*= DHCP6_SERVER_PORT*/, + uint16_t client_port /*= 0*/) : Dhcpv6Srv(server_port, client_port), timer_mgr_(TimerMgr::instance()) { if (getInstance()) { isc_throw(InvalidOperation, @@ -1150,17 +1155,23 @@ ControlledDhcpv6Srv::ControlledDhcpv6Srv(uint16_t server_port, CommandMgr::instance().registerCommand("config-reload", std::bind(&ControlledDhcpv6Srv::commandConfigReloadHandler, this, ph::_1, ph::_2)); + CommandMgr::instance().registerCommand("config-set", + std::bind(&ControlledDhcpv6Srv::commandConfigSetHandler, this, ph::_1, ph::_2)); + CommandMgr::instance().registerCommand("config-test", std::bind(&ControlledDhcpv6Srv::commandConfigTestHandler, this, ph::_1, ph::_2)); CommandMgr::instance().registerCommand("config-write", std::bind(&ControlledDhcpv6Srv::commandConfigWriteHandler, this, ph::_1, ph::_2)); + CommandMgr::instance().registerCommand("dhcp-enable", + std::bind(&ControlledDhcpv6Srv::commandDhcpEnableHandler, this, ph::_1, ph::_2)); + CommandMgr::instance().registerCommand("dhcp-disable", std::bind(&ControlledDhcpv6Srv::commandDhcpDisableHandler, this, ph::_1, ph::_2)); - CommandMgr::instance().registerCommand("dhcp-enable", - std::bind(&ControlledDhcpv6Srv::commandDhcpEnableHandler, this, ph::_1, ph::_2)); + CommandMgr::instance().registerCommand("libreload", + std::bind(&ControlledDhcpv6Srv::commandLibReloadHandler, this, ph::_1, ph::_2)); CommandMgr::instance().registerCommand("leases-reclaim", std::bind(&ControlledDhcpv6Srv::commandLeasesReclaimHandler, this, ph::_1, ph::_2)); @@ -1168,12 +1179,6 @@ ControlledDhcpv6Srv::ControlledDhcpv6Srv(uint16_t server_port, CommandMgr::instance().registerCommand("server-tag-get", std::bind(&ControlledDhcpv6Srv::commandServerTagGetHandler, this, ph::_1, ph::_2)); - CommandMgr::instance().registerCommand("libreload", - std::bind(&ControlledDhcpv6Srv::commandLibReloadHandler, this, ph::_1, ph::_2)); - - CommandMgr::instance().registerCommand("config-set", - std::bind(&ControlledDhcpv6Srv::commandConfigSetHandler, this, ph::_1, ph::_2)); - CommandMgr::instance().registerCommand("shutdown", std::bind(&ControlledDhcpv6Srv::commandShutdownHandler, this, ph::_1, ph::_2)); @@ -1187,18 +1192,18 @@ ControlledDhcpv6Srv::ControlledDhcpv6Srv(uint16_t server_port, CommandMgr::instance().registerCommand("statistic-get", std::bind(&StatsMgr::statisticGetHandler, ph::_1, ph::_2)); - CommandMgr::instance().registerCommand("statistic-get-all", - std::bind(&StatsMgr::statisticGetAllHandler, ph::_1, ph::_2)); - CommandMgr::instance().registerCommand("statistic-reset", std::bind(&StatsMgr::statisticResetHandler, ph::_1, ph::_2)); - CommandMgr::instance().registerCommand("statistic-reset-all", - std::bind(&StatsMgr::statisticResetAllHandler, ph::_1, ph::_2)); - CommandMgr::instance().registerCommand("statistic-remove", std::bind(&StatsMgr::statisticRemoveHandler, ph::_1, ph::_2)); + CommandMgr::instance().registerCommand("statistic-get-all", + std::bind(&StatsMgr::statisticGetAllHandler, ph::_1, ph::_2)); + + CommandMgr::instance().registerCommand("statistic-reset-all", + std::bind(&StatsMgr::statisticResetAllHandler, ph::_1, ph::_2)); + CommandMgr::instance().registerCommand("statistic-remove-all", std::bind(&StatsMgr::statisticRemoveAllHandler, ph::_1, ph::_2)); diff --git a/src/bin/dhcp6/ctrl_dhcp6_srv.h b/src/bin/dhcp6/ctrl_dhcp6_srv.h index 41c2a223e3..41833de59d 100644 --- a/src/bin/dhcp6/ctrl_dhcp6_srv.h +++ b/src/bin/dhcp6/ctrl_dhcp6_srv.h @@ -80,11 +80,18 @@ public: /// in them. /// /// Currently supported commands are: - /// - config-reload - /// - config-test /// - shutdown /// - libreload + /// - config-reload + /// - config-set + /// - config-get + /// - config-test + /// - dhcp-disable + /// - dhcp-enable + /// - version-get + /// - build-report /// - leases-reclaim + /// - config-write /// ... /// /// @note It never throws. @@ -140,7 +147,6 @@ public: } private: - /// @brief Callback that will be called from iface_mgr when data /// is received over control socket. /// diff --git a/src/bin/netconf/http_control_socket.cc b/src/bin/netconf/http_control_socket.cc index 7396488994..2546eb9f45 100644 --- a/src/bin/netconf/http_control_socket.cc +++ b/src/bin/netconf/http_control_socket.cc @@ -79,7 +79,7 @@ HttpControlSocket::sendCommand(ConstElementPtr command) { } IOServicePtr io_service(new IOService()); - HttpClient client(*io_service); + HttpClient client(*io_service, false); boost::system::error_code received_ec; string receive_errmsg; HttpResponseJsonPtr response(new HttpResponseJson()); diff --git a/src/hooks/dhcp/high_availability/ha_service.cc b/src/hooks/dhcp/high_availability/ha_service.cc index a3951dc7cb..8ddfc3dd74 100644 --- a/src/hooks/dhcp/high_availability/ha_service.cc +++ b/src/hooks/dhcp/high_availability/ha_service.cc @@ -93,10 +93,10 @@ HAService::HAService(const IOServicePtr& io_service, const NetworkStatePtr& netw // Create the client and(or) listener as appropriate. if (!config_->getEnableMultiThreading()) { // Not configured for multi-threading, start a client in ST mode. - client_.reset(new HttpClient(*io_service_, 0)); + client_.reset(new HttpClient(*io_service_, false)); } else { // Create an MT-mode client. - client_.reset(new HttpClient(*io_service_, + client_.reset(new HttpClient(*io_service_, true, config_->getHttpClientThreads(), true)); // If we're configured to use our own listener create and start it. @@ -2263,7 +2263,7 @@ int HAService::synchronize(std::string& status_message, const std::string& server_name, const unsigned int max_period) { IOService io_service; - HttpClient client(io_service); + HttpClient client(io_service, false); asyncSyncLeases(client, server_name, max_period, Lease4Ptr(), [&](const bool success, const std::string& error_message, @@ -2468,7 +2468,7 @@ HAService::sendLeaseUpdatesFromBacklog() { } IOService io_service; - HttpClient client(io_service); + HttpClient client(io_service, false); auto remote_config = config_->getFailoverPeerConfig(); bool updates_successful = true; @@ -2553,7 +2553,7 @@ HAService::asyncSendHAReset(HttpClient& http_client, bool HAService::sendHAReset() { IOService io_service; - HttpClient client(io_service); + HttpClient client(io_service, false); auto remote_config = config_->getFailoverPeerConfig(); bool reset_successful = true; @@ -2656,7 +2656,7 @@ HAService::processMaintenanceStart() { HttpResponseJsonPtr response = boost::make_shared(); IOService io_service; - HttpClient client(io_service); + HttpClient client(io_service, false); boost::system::error_code captured_ec; std::string captured_error_message; @@ -2780,7 +2780,7 @@ HAService::processMaintenanceCancel() { HttpResponseJsonPtr response = boost::make_shared(); IOService io_service; - HttpClient client(io_service); + HttpClient client(io_service, false); std::string error_message; diff --git a/src/lib/config/cmd_http_listener.cc b/src/lib/config/cmd_http_listener.cc index be8d7993e2..5fb88046c3 100644 --- a/src/lib/config/cmd_http_listener.cc +++ b/src/lib/config/cmd_http_listener.cc @@ -81,6 +81,9 @@ CmdHttpListener::start() { .arg(port_) .arg(tls_context_ ? "true" : "false"); } catch (const std::exception& ex) { + thread_io_service_.reset(); + http_listener_.reset(); + thread_pool_.reset(); isc_throw(Unexpected, "CmdHttpListener::run failed:" << ex.what()); } } diff --git a/src/lib/http/client.cc b/src/lib/http/client.cc index 42385ed27e..911843b4b0 100644 --- a/src/lib/http/client.cc +++ b/src/lib/http/client.cc @@ -1947,8 +1947,14 @@ private: IoServiceThreadPoolPtr thread_pool_; }; -HttpClient::HttpClient(IOService& io_service, size_t thread_pool_size, - bool defer_thread_start /* = false */) { +HttpClient::HttpClient(IOService& io_service, bool multi_threading_enabled, + size_t thread_pool_size, bool defer_thread_start) { + if (!multi_threading_enabled && thread_pool_size) { + isc_throw(InvalidOperation, + "HttpClient thread_pool_size must be zero " + "when Kea core multi-threading is disabled"); + } + impl_.reset(new HttpClientImpl(io_service, thread_pool_size, defer_thread_start)); } diff --git a/src/lib/http/client.h b/src/lib/http/client.h index f6612c88e2..32c2bf221d 100644 --- a/src/lib/http/client.h +++ b/src/lib/http/client.h @@ -134,6 +134,7 @@ public: /// @brief Constructor. /// /// @param io_service IO service to be used by the HTTP client. + /// @param multi_threading_enabled The flag which indicates if MT is enabled. /// @param thread_pool_size maximum number of threads in the thread pool. /// A value greater than zero enables multi-threaded mode and sets the /// maximum number of concurrent connections per URL. A value of zero @@ -144,7 +145,9 @@ public: /// the thread pool threads will be created and started, with the /// operational state being RUNNING. Applicable only when thread-pool size /// is greater than zero. - explicit HttpClient(asiolink::IOService& io_service, size_t thread_pool_size = 0, + explicit HttpClient(asiolink::IOService& io_service, + bool multi_threading_enabled, + size_t thread_pool_size = 0, bool defer_thread_start = false); /// @brief Destructor. diff --git a/src/lib/http/tests/client_mt_unittests.cc b/src/lib/http/tests/client_mt_unittests.cc index e6b98556e6..ef04c28c60 100644 --- a/src/lib/http/tests/client_mt_unittests.cc +++ b/src/lib/http/tests/client_mt_unittests.cc @@ -481,7 +481,9 @@ public: } // Create an MT client with num_threads - ASSERT_NO_THROW_LOG(client_.reset(new HttpClient(io_service_, num_threads, true))); + ASSERT_NO_THROW_LOG(client_.reset(new HttpClient(io_service_, + num_threads ? true : false, + num_threads, true))); ASSERT_TRUE(client_); if (num_threads_ == 0) { @@ -647,7 +649,7 @@ public: } // Create an instant start, MT client with num_threads - ASSERT_NO_THROW_LOG(client_.reset(new HttpClient(io_service_, num_threads, true))); + ASSERT_NO_THROW_LOG(client_.reset(new HttpClient(io_service_, true, num_threads, true))); ASSERT_TRUE(client_); // Start the requisite number of requests: @@ -830,11 +832,10 @@ public: // Verifies we can construct and destruct, in both single // and multi-threaded modes. TEST_F(MultiThreadingHttpClientTest, basics) { - MultiThreadingMgr::instance().setMode(false); HttpClientPtr client; // Value of 0 for thread_pool_size means single-threaded. - ASSERT_NO_THROW_LOG(client.reset(new HttpClient(io_service_, 0))); + ASSERT_NO_THROW_LOG(client.reset(new HttpClient(io_service_, false))); ASSERT_TRUE(client); ASSERT_FALSE(client->getThreadIOService()); @@ -844,11 +845,14 @@ TEST_F(MultiThreadingHttpClientTest, basics) { // Make sure destruction doesn't throw. ASSERT_NO_THROW_LOG(client.reset()); - // Enable Kea core multi-threading. - MultiThreadingMgr::instance().setMode(true); + // Non-zero thread-pool-size means multi-threaded mode, should throw. + ASSERT_THROW_MSG(client.reset(new HttpClient(io_service_, false, 1)), InvalidOperation, + "HttpClient thread_pool_size must be zero " + "when Kea core multi-threading is disabled"); + ASSERT_FALSE(client); // Multi-threaded construction should work now. - ASSERT_NO_THROW_LOG(client.reset(new HttpClient(io_service_, 3))); + ASSERT_NO_THROW_LOG(client.reset(new HttpClient(io_service_, true, 3))); ASSERT_TRUE(client); // Verify that it has an internal IOService and that thread pool size @@ -884,7 +888,7 @@ TEST_F(MultiThreadingHttpClientTest, basics) { ASSERT_NO_THROW_LOG(client.reset()); // Create another multi-threaded instance. - ASSERT_NO_THROW_LOG(client.reset(new HttpClient(io_service_, 3))); + ASSERT_NO_THROW_LOG(client.reset(new HttpClient(io_service_, true, 3))); // Make sure destruction doesn't throw. ASSERT_NO_THROW_LOG(client.reset()); @@ -892,12 +896,11 @@ TEST_F(MultiThreadingHttpClientTest, basics) { // Verifies we can construct with deferred start. TEST_F(MultiThreadingHttpClientTest, deferredStart) { - MultiThreadingMgr::instance().setMode(true); HttpClientPtr client; size_t thread_pool_size = 3; // Create MT client with deferred start. - ASSERT_NO_THROW_LOG(client.reset(new HttpClient(io_service_, thread_pool_size, true))); + ASSERT_NO_THROW_LOG(client.reset(new HttpClient(io_service_, true, thread_pool_size, true))); ASSERT_TRUE(client); // Client should be STOPPED, with no threads. @@ -936,12 +939,11 @@ TEST_F(MultiThreadingHttpClientTest, deferredStart) { // Verifies we can restart after stop. TEST_F(MultiThreadingHttpClientTest, restartAfterStop) { - MultiThreadingMgr::instance().setMode(true); HttpClientPtr client; size_t thread_pool_size = 3; // Create MT client with instant start. - ASSERT_NO_THROW_LOG(client.reset(new HttpClient(io_service_, thread_pool_size))); + ASSERT_NO_THROW_LOG(client.reset(new HttpClient(io_service_, true, thread_pool_size))); ASSERT_TRUE(client); // Verify we're started. diff --git a/src/lib/http/tests/server_client_unittests.cc b/src/lib/http/tests/server_client_unittests.cc index 4ca280d350..7cb66671dd 100644 --- a/src/lib/http/tests/server_client_unittests.cc +++ b/src/lib/http/tests/server_client_unittests.cc @@ -1064,7 +1064,7 @@ public: ASSERT_NO_THROW(listener_.start()); // Create a client and specify the URL on which the server can be reached. - HttpClient client(io_service_); + HttpClient client(io_service_, false); Url url("http://127.0.0.1:18123"); // Initiate request to the server. @@ -1122,7 +1122,7 @@ public: ASSERT_NO_THROW(listener2_.start()); // Create the client. It will be communicating with the two servers. - HttpClient client(io_service_); + HttpClient client(io_service_, false); // Specify the URLs on which the servers are available. Url url1("http://127.0.0.1:18123"); @@ -1179,7 +1179,7 @@ public: ASSERT_NO_THROW(listener_.start()); // Create the client. - HttpClient client(io_service_); + HttpClient client(io_service_, false); // Specify the URL on which the server is available. Url url("http://127.0.0.1:18123"); @@ -1239,7 +1239,7 @@ public: ASSERT_NO_THROW(listener3_.start()); // Create the client that will communicate with this server. - HttpClient client(io_service_); + HttpClient client(io_service_, false); // Specify the URL of this server. Url url("http://127.0.0.1:18125"); @@ -1294,7 +1294,7 @@ public: /// server is unreachable. void testUnreachable () { // Create the client. - HttpClient client(io_service_); + HttpClient client(io_service_, false); // Specify the URL of the server. This server is down. Url url("http://127.0.0.1:18123"); @@ -1323,7 +1323,7 @@ public: ASSERT_NO_THROW(listener_.start()); // Create the client. - HttpClient client(io_service_); + HttpClient client(io_service_, false); // Specify the URL of the server. Url url("http://127.0.0.1:18123"); @@ -1360,7 +1360,7 @@ public: ASSERT_NO_THROW(listener_.start()); // Create the client. - HttpClient client(io_service_); + HttpClient client(io_service_, false); // Specify the URL of the server. Url url("http://127.0.0.1:18123"); @@ -1425,7 +1425,7 @@ public: ASSERT_NO_THROW(listener_.start()); // Create the client. - HttpClient client(io_service_); + HttpClient client(io_service_, false); // Specify the URL of the server. Url url("http://127.0.0.1:18123"); @@ -1499,7 +1499,7 @@ public: ASSERT_NO_THROW(listener_.start()); // Create the client. - HttpClient client(io_service_); + HttpClient client(io_service_, false); // Specify the URL of the server. Url url("http://127.0.0.1:18123"); @@ -1582,7 +1582,7 @@ public: ASSERT_NO_THROW(listener_.start()); // Create a client and specify the URL on which the server can be reached. - HttpClient client(io_service_); + HttpClient client(io_service_, false); Url url("http://127.0.0.1:18123"); // Initiate request to the server. @@ -1677,7 +1677,7 @@ public: ASSERT_NO_THROW(listener_.start()); // Create a client and specify the URL on which the server can be reached. - HttpClient client(io_service_); + HttpClient client(io_service_, false); Url url("http://127.0.0.1:18123"); // Initiate request to the server. diff --git a/src/lib/http/tests/tls_client_unittests.cc b/src/lib/http/tests/tls_client_unittests.cc index 4d82e95640..5828fb0bd8 100644 --- a/src/lib/http/tests/tls_client_unittests.cc +++ b/src/lib/http/tests/tls_client_unittests.cc @@ -359,7 +359,7 @@ public: ASSERT_NO_THROW(listener_->start()); // Create a client and specify the URL on which the server can be reached. - HttpClient client(io_service_); + HttpClient client(io_service_, false); Url url("http://127.0.0.1:18123"); // Initiate request to the server. @@ -421,7 +421,7 @@ public: ASSERT_NO_THROW(listener2_->start()); // Create the client. It will be communicating with the two servers. - HttpClient client(io_service_); + HttpClient client(io_service_, false); // Specify the URLs on which the servers are available. Url url1("http://127.0.0.1:18123"); @@ -482,7 +482,7 @@ public: ASSERT_NO_THROW(listener_->start()); // Create the client. - HttpClient client(io_service_); + HttpClient client(io_service_, false); // Create a second client context. TlsContextPtr client_context2; @@ -550,7 +550,7 @@ public: ASSERT_NO_THROW(listener3_->start()); // Create the client that will communicate with this server. - HttpClient client(io_service_); + HttpClient client(io_service_, false); // Specify the URL of this server. Url url("http://127.0.0.1:18125"); @@ -609,7 +609,7 @@ public: /// server is unreachable. void testUnreachable () { // Create the client. - HttpClient client(io_service_); + HttpClient client(io_service_, false); // Specify the URL of the server. This server is down. Url url("http://127.0.0.1:18123"); @@ -640,7 +640,7 @@ public: ASSERT_NO_THROW(listener_->start()); // Create the client. - HttpClient client(io_service_); + HttpClient client(io_service_, false); // Specify the URL of the server. Url url("http://127.0.0.1:18123"); @@ -679,7 +679,7 @@ public: ASSERT_NO_THROW(listener_->start()); // Create the client. - HttpClient client(io_service_); + HttpClient client(io_service_, false); // Specify the URL of the server. Url url("http://127.0.0.1:18123"); @@ -744,7 +744,7 @@ public: ASSERT_NO_THROW(listener_->start()); // Create the client. - HttpClient client(io_service_); + HttpClient client(io_service_, false); // Specify the URL of the server. Url url("http://127.0.0.1:18123"); @@ -818,7 +818,7 @@ public: ASSERT_NO_THROW(listener_->start()); // Create the client. - HttpClient client(io_service_); + HttpClient client(io_service_, false); // Specify the URL of the server. Url url("http://127.0.0.1:18123"); @@ -903,7 +903,7 @@ public: ASSERT_NO_THROW(listener_->start()); // Create a client and specify the URL on which the server can be reached. - HttpClient client(io_service_); + HttpClient client(io_service_, false); Url url("http://127.0.0.1:18123"); // Initiate request to the server. @@ -1002,7 +1002,7 @@ public: ASSERT_NO_THROW(listener_->start()); // Create a client and specify the URL on which the server can be reached. - HttpClient client(io_service_); + HttpClient client(io_service_, false); Url url("http://127.0.0.1:18123"); // Initiate request to the server. diff --git a/src/lib/tcp/mt_tcp_listener_mgr.cc b/src/lib/tcp/mt_tcp_listener_mgr.cc index d2347785e2..a8afa6d965 100644 --- a/src/lib/tcp/mt_tcp_listener_mgr.cc +++ b/src/lib/tcp/mt_tcp_listener_mgr.cc @@ -78,6 +78,9 @@ MtTcpListenerMgr::start() { .arg(port_) .arg(tls_context_ ? "true" : "false"); } catch (const std::exception& ex) { + thread_io_service_.reset(); + tcp_listener_.reset(); + thread_pool_.reset(); isc_throw(Unexpected, "MtTcpListenerMgr::start failed:" << ex.what()); } }