size_t
CtrlAgentProcess::runIO() {
+ // Handle events registered by hooks using external IOService objects.
IOServiceMgr::instance().pollIOServices();
size_t cnt = getIOService()->poll();
if (!cnt) {
int rcode = 0;
config::parseAnswer(rcode, answer);
- /// Let postponed hook initializations to run.
+ /// Let postponed hook initializations run.
try {
+ // Handle events registered by hooks using external IOService objects.
IOServiceMgr::instance().pollIOServices();
} catch (const std::exception& ex) {
std::ostringstream err;
// We have some cancelled operations for which we need to invoke the
// handlers with the operation_aborted error code.
- getIOService()->stop();
- getIOService()->restart();
- getIOService()->poll();
+ getIOService()->stopAndPoll(false);
EXPECT_EQ(expected_responses, server_socket_->getResponseNum());
checkAnswer(answer, expected_result0, expected_result1, expected_result2);
// We have some cancelled operations for which we need to invoke the
// handlers with the operation_aborted error code.
- getIOService()->stop();
- getIOService()->restart();
- getIOService()->poll();
+ getIOService()->stopAndPoll(false);
// Answer of 3 is specific to the stub response we send when the
// command is forwarded. So having this value returned means that
elapsed.total_milliseconds() <= 400);
timer.cancel();
- getIOService()->stop();
- getIOService()->restart();
- try {
- getIOService()->poll();
- } catch (...) {
- }
+ getIOService()->stopAndPoll();
}
}
its (re)configuration. The server provides received and parsed configuration
structures to the hook library.
If the library uses any IO operations, it should create a local IOService
- object and register it to the IOServiceMgr. This way the local IOService is
+ object and register it with the IOServiceMgr. This way the local IOService is
used by the server to run asynchronous operations. The hooks library can use
the local IOService object to schedule asynchronous tasks which are triggered
by the D2 server's main loop. The hook library can use the local IOService
size_t
D2Process::runIO() {
+ // Handle events registered by hooks using external IOService objects.
IOServiceMgr::instance().pollIOServices();
// We want to block until at least one handler is called. We'll use
// boost::asio::io_service directly for two reasons. First off
}
}
- /// Let postponed hook initializations to run.
+ /// Let postponed hook initializations run.
try {
+ // Handle events registered by hooks using external IOService objects.
IOServiceMgr::instance().pollIOServices();
} catch (const std::exception& ex) {
std::ostringstream err;
D2Process::~D2Process() {
queue_mgr_->stopListening();
- getIOService()->stop();
- getIOService()->restart();
- try {
- getIOService()->poll();
- } catch (...) {
- }
+ getIOService()->stopAndPoll();
queue_mgr_->removeListener();
}
elapsed.total_milliseconds() <= 2200);
timer.cancel();
- getIOService()->stop();
- getIOService()->restart();
- try {
- getIOService()->poll();
- } catch (...) {
- }
+ getIOService()->stopAndPoll();
}
/// @brief Verifies that an "uncaught" exception thrown during event loop
elapsed.total_milliseconds() <= 2200);
timer.cancel();
- getIOService()->stop();
- getIOService()->restart();
- try {
- getIOService()->poll();
- } catch (...) {
- }
+ getIOService()->stopAndPoll();
}
/// @brief Used to permit visual inspection of logs to ensure
sender_->stopSending();
queue_mgr_->stopListening();
test_timer_.cancel();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
queue_mgr_->removeListener();
}
if (server_) {
server_->stop();
}
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief Creates a list of valid NameChangeRequest.
LOG_FATAL(dhcp4_logger, DHCP4_CONFIG_UNRECOVERABLE_ERROR);
}
- /// Let postponed hook initializations to run.
+ /// Let postponed hook initializations run.
try {
+ // Handle events registered by hooks using external IOService objects.
IOServiceMgr::instance().pollIOServices();
} catch (const std::exception& ex) {
std::ostringstream err;
its (re)configuration. The server provides received and parsed configuration
structures to the hook library.
If the library uses any IO operations, it should create a local IOService
- object and register it to the IOServiceMgr. This way the local IOService is
+ object and register it with the IOServiceMgr. This way the local IOService is
used by the server to run asynchronous operations. The hooks library can use
the local IOService object to schedule asynchronous tasks which are triggered
by the DHCP server's main loop. The hook library can use the local IOService
LOG_ERROR(dhcp4_logger, DHCP4_SRV_UNLOAD_LIBRARIES_ERROR).arg(msg);
}
IOServiceMgr::instance().clearIOServices();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
void
#endif // ENABLE_AFL
try {
runOne();
+ // Handle events registered by hooks using external IOService objects.
IOServiceMgr::instance().pollIOServices();
getIOService()->poll();
} catch (const std::exception& e) {
return (notify_libraries);
}
- /// Let postponed hook initializations to run.
+ /// Let postponed hook initializations run.
try {
+ // Handle events registered by hooks using external IOService objects.
IOServiceMgr::instance().pollIOServices();
} catch (const std::exception& ex) {
std::ostringstream err;
LOG_FATAL(dhcp6_logger, DHCP6_CONFIG_UNRECOVERABLE_ERROR);
}
- /// Let postponed hook initializations to run.
+ /// Let postponed hook initializations run.
try {
+ // Handle events registered by hooks using external IOService objects.
IOServiceMgr::instance().pollIOServices();
} catch (const std::exception& ex) {
std::ostringstream err;
its (re)configuration. The server provides received and parsed configuration
structures to the hook library.
If the library uses any IO operations, it should create a local IOService
- object and register it to the IOServiceMgr. This way the local IOService is
+ object and register it with the IOServiceMgr. This way the local IOService is
used by the server to run asynchronous operations. The hooks library can use
the local IOService object to schedule asynchronous tasks which are triggered
by the DHCP server's main loop. The hook library can use the local IOService
LOG_ERROR(dhcp6_logger, DHCP6_SRV_UNLOAD_LIBRARIES_ERROR).arg(msg);
}
IOServiceMgr::instance().clearIOServices();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
void Dhcpv6Srv::shutdown() {
#endif // ENABLE_AFL
try {
runOne();
+ // Handle events registered by hooks using external IOService objects.
IOServiceMgr::instance().pollIOServices();
getIOService()->poll();
} catch (const std::exception& e) {
return (notify_libraries);
}
- /// Let postponed hook initializations to run.
+ /// Let postponed hook initializations run.
try {
+ // Handle events registered by hooks using external IOService objects.
IOServiceMgr::instance().pollIOServices();
} catch (const std::exception& ex) {
std::ostringstream err;
# Path to test hooks library
HOOK_FAIL_LOAD_PATH="@abs_top_builddir@/src/bin/dhcp6/tests/.libs/libco3.so"
# Path to test hooks library
-HOOK_FAIL_POLL_PATH="@abs_top_builddir@/src/bin/dhcp6/tests/.libs/libco3.so"
+HOOK_FAIL_POLL_PATH="@abs_top_builddir@/src/bin/dhcp6/tests/.libs/libco4.so"
# Kea configuration to be stored in the configuration file.
CONFIG="{
\"Dhcp6\":
virtual ~NakedDhcpv6Srv() {
// Close the lease database
isc::dhcp::LeaseMgrFactory::destroy();
- getIOService()->stop();
- getIOService()->restart();
- try {
- getIOService()->poll();
- } catch (...) {
- }
+ getIOService()->stopAndPoll();
}
/// @brief Processes incoming Solicit message.
io_service->run();
client.stop();
- io_service->stop();
- io_service->restart();
- try {
- io_service->poll();
- } catch (...) {
- }
+ io_service->stopAndPoll();
if (received_ec) {
// Got an error code.
size_t
NetconfProcess::runIO() {
+ // Handle events registered by hooks using external IOService objects.
IOServiceMgr::instance().pollIOServices();
size_t cnt = getIOService()->poll();
if (!cnt) {
int rcode = 0;
config::parseAnswer(rcode, answer);
- /// Let postponed hook initializations to run.
+ /// Let postponed hook initializations run.
try {
+ // Handle events registered by hooks using external IOService objects.
IOServiceMgr::instance().pollIOServices();
} catch (const std::exception& ex) {
std::ostringstream err;
thread_.reset();
}
removeUnixSocketFile();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief Returns socket file path.
if (listener_) {
listener_->stop();
}
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
listener_.reset();
}
EXPECT_TRUE(elapsed.total_milliseconds() >= 100 &&
elapsed.total_milliseconds() <= 400);
timer.cancel();
- getIOService()->stop();
- getIOService()->restart();
- try {
- getIOService()->poll();
- } catch (...) {
- }
+ getIOService()->stopAndPoll();
}
}
responses_.clear();
removeUnixSocketFile();
SysrepoSetup::cleanSharedMemory();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief Returns socket file path.
which executes callbacks for completed asynchronous operations, such as
timers, asynchronous sends and receives. The instance of the IOService
is owned by the DHCP servers, but hooks libraries must create their own
-IOService access to schedule asynchronous tasks.
-The hook's IOService object must be registered on the IOServiceMgr by
+IOService to schedule asynchronous tasks.
+The hook's IOService object must be registered with the IOServiceMgr by
calling registerIOService and must unregister it on "unload" hook point
by calling unregisterIOService.
[...]
try {
runOne();
+ // Handle events registered by hooks using external IOService objects.
IOServiceMgr::instance().pollIOServices();
getIOService()->poll();
} catch (const std::exception& e) {
int unload() {
if (impl) {
IOServiceMgr::instance().unregisterIOService(impl->getIOService());
- impl->getIOService()->stop();
- impl->getIOService()->restart();
- try {
- impl->getIOService()->poll();
- } catch (...) {
- }
+ impl->getIOService()->stopAndPoll();
}
impl.reset();
LOG_INFO(ha_logger, HA_DEINIT_OK);
client.stop();
- io_service->stop();
- io_service->restart();
- try {
- io_service->poll();
- } catch (...) {
- }
+ io_service->stopAndPoll();
// If an error message has been recorded, return an error to the controlling
// client.
client.stop();
- io_service->stop();
- io_service->restart();
- try {
- io_service->poll();
- } catch (...) {
- }
+ io_service->stopAndPoll();
if (updates_successful) {
LOG_INFO(ha_logger, HA_LEASES_BACKLOG_SUCCESS)
client.stop();
- io_service->stop();
- io_service->restart();
- try {
- io_service->poll();
- } catch (...) {
- }
+ io_service->stopAndPoll();
return (reset_successful);
}
client.stop();
- io_service->stop();
- io_service->restart();
- try {
- io_service->poll();
- } catch (...) {
- }
+ io_service->stopAndPoll();
// If there was a communication problem with the partner we assume that
// the partner is already down while we receive this command.
client.stop();
- io_service->stop();
- io_service->restart();
- try {
- io_service->poll();
- } catch (...) {
- }
+ io_service->stopAndPoll();
// There was an error in communication with the partner or the
// partner was unable to revert its state.
/// @brief Destructor.
~HAImplTest() {
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
ha_impl_.reset();
test_ha_impl_.reset();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
// Clear statistics.
StatsMgr::instance().removeAll();
}
checkAnswer(response, CONTROL_RESULT_ERROR, expected_response);
callout_handle.reset();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
ha_impl_.reset();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief HA Instance under test.
///
/// Stops all test servers.
~HAMtServiceTest() {
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
MultiThreadingMgr::instance().setMode(false);
CmdResponseCreator::command_accept_list_.clear();
}
listener_->stop();
listener2_->stop();
listener3_->stop();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
MultiThreadingMgr::instance().setMode(false);
CfgMgr::instance().clear();
}
// Change the partner's response to success.
factory2_->getResponseCreator()->setControlResult(CONTROL_RESULT_SUCCESS);
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
// Try sending the lease updates again. The previously rejected lease should
// now be accepted and the counter should be 0.
}
~HAServiceStateMachineTest() {
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief Creates common HA service instance from the provided configuration.
if (timer_) {
timer_->cancel();
}
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
void
/// @param handle callout handle passed to the callout.
/// @return 0 on success, 1 otherwise.
int dhcp4_srv_configured(CalloutHandle& handle) {
- isc::dhcp::MySqlConfigBackendImpl::getIOService().reset(new IOService());
+ isc::dhcp::MySqlConfigBackendImpl::setIOService(IOServicePtr(new IOService()));
IOServiceMgr::instance().registerIOService(isc::dhcp::MySqlConfigBackendImpl::getIOService());
return (0);
}
/// @param handle callout handle passed to the callout.
/// @return 0 on success, 1 otherwise.
int dhcp6_srv_configured(CalloutHandle& handle) {
- isc::dhcp::MySqlConfigBackendImpl::getIOService().reset(new IOService());
+ isc::dhcp::MySqlConfigBackendImpl::setIOService(IOServicePtr(new IOService()));
IOServiceMgr::instance().registerIOService(isc::dhcp::MySqlConfigBackendImpl::getIOService());
return (0);
}
isc::dhcp::MySqlConfigBackendDHCPv6::unregisterBackendType();
IOServiceMgr::instance().unregisterIOService(isc::dhcp::MySqlConfigBackendImpl::getIOService());
if (isc::dhcp::MySqlConfigBackendImpl::getIOService()) {
- isc::dhcp::MySqlConfigBackendImpl::getIOService()->stop();
- isc::dhcp::MySqlConfigBackendImpl::getIOService()->restart();
- try {
- isc::dhcp::MySqlConfigBackendImpl::getIOService()->poll();
- } catch (...) {
- }
+ isc::dhcp::MySqlConfigBackendImpl::getIOService()->stopAndPoll();
}
return (0);
}
/// @param handle callout handle passed to the callout.
/// @return 0 on success, 1 otherwise.
int dhcp4_srv_configured(CalloutHandle& handle) {
- isc::dhcp::PgSqlConfigBackendImpl::getIOService().reset(new IOService());
+ isc::dhcp::PgSqlConfigBackendImpl::setIOService(IOServicePtr(new IOService()));
IOServiceMgr::instance().registerIOService(isc::dhcp::PgSqlConfigBackendImpl::getIOService());
return (0);
}
/// @param handle callout handle passed to the callout.
/// @return 0 on success, 1 otherwise.
int dhcp6_srv_configured(CalloutHandle& handle) {
- isc::dhcp::PgSqlConfigBackendImpl::getIOService().reset(new IOService());
+ isc::dhcp::PgSqlConfigBackendImpl::setIOService(IOServicePtr(new IOService()));
IOServiceMgr::instance().registerIOService(isc::dhcp::PgSqlConfigBackendImpl::getIOService());
return (0);
}
isc::dhcp::PgSqlConfigBackendDHCPv6::unregisterBackendType();
IOServiceMgr::instance().unregisterIOService(isc::dhcp::PgSqlConfigBackendImpl::getIOService());
if (isc::dhcp::PgSqlConfigBackendImpl::getIOService()) {
- isc::dhcp::PgSqlConfigBackendImpl::getIOService()->stop();
- isc::dhcp::PgSqlConfigBackendImpl::getIOService()->restart();
- try {
- isc::dhcp::PgSqlConfigBackendImpl::getIOService()->poll();
- } catch (...) {
- }
+ isc::dhcp::PgSqlConfigBackendImpl::getIOService()->stopAndPoll();
}
return (0);
}
virtual ~IOFetchTest() {
shutdown_ = true;
timer_.cancel();
- service_->stop();
- service_->restart();
- try {
- service_->poll();
- } catch (...) {
- }
+ service_->stopAndPoll();
}
/// \brief UDP Response handler (the "remote UDP DNS server")
return (io_impl_->post(callback));
}
+void
+IOService::stopAndPoll(bool ignore_errors) {
+ stop();
+ restart();
+ if (ignore_errors) {
+ try {
+ poll();
+ } catch (...) {
+ // Ignore all exceptions.
+ }
+ } else {
+ poll();
+ }
+}
+
} // namespace asiolink
} // namespace isc
/// by small bits that are called from time to time).
void post(const std::function<void ()>& callback);
+ /// @brief Stop and poll to handle all registered events.
+ ///
+ /// @param ignore_errors Flag which indicates if errors should be ignored.
+ void stopAndPoll(bool ignore_errors = true);
+
private:
/// @brief The implementation.
void
IOServiceMgr::registerIOService(IOServicePtr io_service) {
- io_services_.push_back(io_service);
+ if (!io_service) {
+ return;
+ }
+ auto it = std::find(io_services_.begin(), io_services_.end(), io_service);
+ if (it == io_services_.end()) {
+ io_services_.push_back(io_service);
+ }
}
void
class IOServiceMgr;
+/// @brief Class which handles events on IOService objects.
+///
+/// Usually hook libraries create a local IOService object which handles events
+/// related to the respective library. To be able to handle these events, the
+/// IOService objects need to be registered on the '[X]_srv_configured' or
+/// on 'load' hook points (before the MT settings are applied).
+/// This class is not thread safe, so all operations must be done on the main
+/// thread, while all other threads are either stopped or paused.
class IOServiceMgr : boost::noncopyable {
public:
/// @brief Register IOService.
///
+ /// Registering a null IOService does nothing.
+ /// One IOService object can be registered only once, all consecutive calls
+ /// using the same object will be silently ignored.
+ ///
/// @param io_service The IOService to be registered.
void registerIOService(IOServicePtr io_service);
/// @brief Unregister IOService.
///
+ /// Unregistering an non registered IOService object will be silently
+ /// ignored.
+ ///
/// @param io_service The IOService to be unregistered.
void unregisterIOService(IOServicePtr io_service);
/// @param pid the pid to wait for, -1 by default meaning wait
/// for any child process
/// @param sync whether this function is called immediately after spawning
- /// (synchronous) or not (asynchronous, default).
+ /// (synchronous) or not (asynchronous).
static void waitForProcess(int signum, pid_t const wpid = -1,
bool const sync = false);
static ProcessCollection process_collection_;
/// @brief Whether the process is waited immediately after spawning
- /// (synchronous) or not (asynchronous, default).
+ /// (synchronous) or not (asynchronous).
bool sync_;
/// @brief Path to an executable.
timer_cancel_success_(false) {
}
~IntervalTimerTest() {
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
class TimerCallBack {
public:
namespace {
-TEST(IOServiceMgr, testIOServiceMgr) {
+// Test if IOServiceMgr behaves like a singleton.
+TEST(IOServiceMgr, singleton) {
+ IOServiceMgr& one(IOServiceMgr::instance());
+ IOServiceMgr& two(IOServiceMgr::instance());
+ EXPECT_EQ(&one, &two);
+ EXPECT_FALSE(std::is_copy_constructible<IOServiceMgr>::value);
+}
+
+// Test exceptional cases.
+TEST(IOServiceMgr, noError) {
+ EXPECT_EQ(IOServiceMgr::instance().getIOServiceCount(), 0);
+ // Regiter null IOService.
+ ASSERT_NO_THROW(IOServiceMgr::instance().registerIOService(IOServicePtr()));
+ EXPECT_EQ(IOServiceMgr::instance().getIOServiceCount(), 0);
+ // Unregister null IOService.
+ ASSERT_NO_THROW(IOServiceMgr::instance().unregisterIOService(IOServicePtr()));
+ EXPECT_EQ(IOServiceMgr::instance().getIOServiceCount(), 0);
+ // Unregister not registered IOService.
+ ASSERT_NO_THROW(IOServiceMgr::instance().unregisterIOService(IOServicePtr(new IOService())));
+ EXPECT_EQ(IOServiceMgr::instance().getIOServiceCount(), 0);
+}
+
+// Create two IOService objects in a local scope and check that all events
+// already registered are handled after local scope ends.
+TEST(IOServiceMgr, testIOServiceMgrLocalIOServies) {
EXPECT_EQ(IOServiceMgr::instance().getIOServiceCount(), 0);
int one_io_callback_count = 0;
auto one_f = [&one_io_callback_count] () {
auto two_f = [&two_io_callback_count] () {
two_io_callback_count++;
};
+
{
IOServicePtr one_io_service(new IOService());
one_io_service->post(one_f);
IOServiceMgr::instance().clearIOServices();
EXPECT_EQ(IOServiceMgr::instance().getIOServiceCount(), 0);
+}
+
+// Create two IOService objects and test register, unregister and poll.
+TEST(IOServiceMgr, testIOServiceMgrRegisterAndUnregister) {
+ EXPECT_EQ(IOServiceMgr::instance().getIOServiceCount(), 0);
+ int one_io_callback_count = 0;
+ auto one_f = [&one_io_callback_count] () {
+ one_io_callback_count++;
+ };
+ int two_io_callback_count = 0;
+ auto two_f = [&two_io_callback_count] () {
+ two_io_callback_count++;
+ };
IOServicePtr one_io_service(new IOService());
one_io_service->post(one_f);
two_io_service->post(two_f);
IOServiceMgr::instance().pollIOServices();
- EXPECT_EQ(one_io_callback_count, 2);
- EXPECT_EQ(two_io_callback_count, 2);
+ EXPECT_EQ(one_io_callback_count, 0);
+ EXPECT_EQ(two_io_callback_count, 0);
IOServiceMgr::instance().registerIOService(one_io_service);
EXPECT_EQ(IOServiceMgr::instance().getIOServiceCount(), 1);
IOServiceMgr::instance().pollIOServices();
- EXPECT_EQ(one_io_callback_count, 3);
- EXPECT_EQ(two_io_callback_count, 2);
+ EXPECT_EQ(one_io_callback_count, 1);
+ EXPECT_EQ(two_io_callback_count, 0);
one_io_service->post(one_f);
two_io_service->post(two_f);
EXPECT_EQ(IOServiceMgr::instance().getIOServiceCount(), 2);
IOServiceMgr::instance().pollIOServices();
- EXPECT_EQ(one_io_callback_count, 4);
- EXPECT_EQ(two_io_callback_count, 4);
+ EXPECT_EQ(one_io_callback_count, 2);
+ EXPECT_EQ(two_io_callback_count, 2);
one_io_service->post(one_f);
two_io_service->post(two_f);
+ ASSERT_NO_THROW(IOServiceMgr::instance().registerIOService(one_io_service));
+ EXPECT_EQ(IOServiceMgr::instance().getIOServiceCount(), 2);
+
IOServiceMgr::instance().unregisterIOService(one_io_service);
EXPECT_EQ(IOServiceMgr::instance().getIOServiceCount(), 1);
IOServiceMgr::instance().pollIOServices();
- EXPECT_EQ(one_io_callback_count, 4);
- EXPECT_EQ(two_io_callback_count, 5);
+ EXPECT_EQ(one_io_callback_count, 2);
+ EXPECT_EQ(two_io_callback_count, 3);
one_io_service->post(one_f);
two_io_service->post(two_f);
EXPECT_EQ(IOServiceMgr::instance().getIOServiceCount(), 0);
IOServiceMgr::instance().pollIOServices();
- EXPECT_EQ(one_io_callback_count, 4);
- EXPECT_EQ(two_io_callback_count, 5);
+ EXPECT_EQ(one_io_callback_count, 2);
+ EXPECT_EQ(two_io_callback_count, 3);
}
} // namespace
io_signal_set_->remove(SIGCHLD);
io_signal_set_.reset();
// Make sure the cancel handler for the IOSignalSet is called.
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief Method used as the IOSignalSet handler.
virtual ~TCPAcceptorTest() {
running_ = false;
test_timer_.cancel();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief Specifies how many new connections are expected before the IO
virtual ~TLSAcceptorTest() {
running_ = false;
test_timer_.cancel();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief Specifies how many new connections are expected before the IO
/// @brief Destructor.
virtual ~TLSTest() {
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief IO service.
virtual ~UnixDomainSocketTest() {
removeUnixSocketFile();
test_socket_.reset();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief Returns socket file path.
}
if (thread_io_service_) {
- thread_io_service_->stop();
- thread_io_service_->restart();
- try {
- thread_io_service_->poll();
- } catch (...) {
- }
+ thread_io_service_->stopAndPoll();
thread_io_service_->stop();
}
// Stop the listener.
http_listener_->stop();
- thread_io_service_->stop();
- thread_io_service_->restart();
- try {
- thread_io_service_->poll();
- } catch (...) {
- }
+ thread_io_service_->stopAndPoll();
thread_io_service_->stop();
// Get rid of the thread pool.
removeUnixSocketFile();
conn_.reset();
test_socket_.reset();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief Returns socket file path.
}
test_timer_.cancel();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
// Deregisters commands.
config::CommandMgr::instance().deregisterAll();
virtual ~DNSClientTest() {
test_timer_.cancel();
dns_client_->stop();
- service_->stop();
- service_->restart();
- try {
- service_->poll();
- } catch (...) {
- }
+ service_->stopAndPoll();
asiodns::logger.setSeverity(isc::log::DEBUG);
};
// Since the callback, operator(), calls stop() on the io_service,
// we must reset it in order for subsequent calls to run() or
// runOne() to work.
- service_->stop();
- service_->restart();
- try {
- service_->poll();
- } catch (...) {
- }
+ service_->stopAndPoll();
}
/// @brief Performs a single request-response exchange with or without TSIG.
// Since the callback, operator(), calls stop() on the io_service,
// we must reset it in order for subsequent calls to run() or
// runOne() to work.
- service_->stop();
- service_->restart();
- try {
- service_->poll();
- } catch (...) {
- }
+ service_->stopAndPoll();
}
};
virtual ~NameChangeTransactionTest() {
timer_->cancel();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
io_service_.reset(new IOService());
timer_.reset(new IntervalTimer(io_service_));
}
TimedIO::~TimedIO() {
timer_->cancel();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
int
if (io_service_) {
try {
- io_service_->stop();
- io_service_->restart();
- io_service_->poll();
+ io_service_->stopAndPoll(false);
} catch (const std::exception& ex) {
// Swallow exceptions. If we have some sort of error we'll log
// it but we won't propagate the throw.
virtual ~NameChangeUDPListenerTest() {
test_timer_.cancel();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief Converts JSON string into an NCR and sends it to the listener.
~NameChangeUDPTest() {
test_timer_.cancel();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
// Disable multi-threading
MultiThreadingMgr::instance().setMode(false);
}
}
if (private_io_service_) {
- private_io_service_->stop();
- private_io_service_->restart();
- try {
- private_io_service_->poll();
- } catch (...) {
- }
+ private_io_service_->stopAndPoll();
}
}
/// timers.
virtual ~CfgExpirationTimersTest() {
cleanupTimerMgr();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief Stop @c TimerMgr worker thread and remove the timers.
// Disable multi-threading.
MultiThreadingMgr::instance().setMode(false);
- getIOService()->stop();
- getIOService()->restart();
- try {
- getIOService()->poll();
- } catch(...) {
- }
+ getIOService()->stopAndPoll();
}
/// @brief Remove files being products of Lease File Cleanup.
TimerMgrTest::TearDown() {
// Remove all timers.
timer_mgr_->unregisterTimers();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
void
}
if (thread_io_service_) {
- thread_io_service_->stop();
- thread_io_service_->restart();
- try {
- thread_io_service_->poll();
- } catch (...) {
- }
+ thread_io_service_->stopAndPoll();
thread_io_service_->stop();
}
}
}
test_timer_.cancel();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
MultiThreadingMgr::instance().setMode(false);
}
/// @brief Destructor.
~HttpConnectionPoolTest() {
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
MultiThreadingMgr::instance().setMode(false);
}
client->close();
}
test_timer_.cancel();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief Connect to the endpoint.
timeout, IntervalTimer::ONE_SHOT);
}
io_service_->run();
- io_service_->stop();
- io_service_->restart();
- io_service_->poll();
+ io_service_->stopAndPoll(false);
}
/// @brief Returns HTTP OK response expected by unit tests.
listener_.stop();
listener2_.stop();
listener3_.stop();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch(...) {
- }
+ io_service_->stopAndPoll();
MultiThreadingMgr::instance().setMode(false);
}
/// @brief Destructor.
virtual ~HttpListenerTest() {
test_timer_.cancel();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief Callback function invoke upon test timeout.
timeout, IntervalTimer::ONE_SHOT);
}
io_service_->run();
- io_service_->stop();
- io_service_->restart();
- io_service_->poll();
+ io_service_->stopAndPoll(false);
}
/// @brief IO service used in the tests.
client->close();
}
test_timer_.cancel();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief Connect to the endpoint.
timeout, IntervalTimer::ONE_SHOT);
}
io_service_->run();
- io_service_->stop();
- io_service_->restart();
- io_service_->poll();
+ io_service_->stopAndPoll(false);
}
/// @brief Returns HTTP OK response expected by unit tests.
/// @brief Destructor
virtual ~DProcessBase() {
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief Checks if the process has been instructed to shut down.
}
if (thread_io_service_) {
- thread_io_service_->stop();
- thread_io_service_->restart();
- try {
- thread_io_service_->poll();
- } catch (...) {
- }
+ thread_io_service_->stopAndPoll();
thread_io_service_->stop();
}
}
LOG_DEBUG(tcp_logger, isc::log::DBGLVL_TRACE_BASIC, MT_TCP_LISTENER_MGR_STOPPING)
- .arg(address_)
- .arg(port_);
+ .arg(address_)
+ .arg(port_);
// Stop the thread pool.
thread_pool_->stop();
// Stop the listener.
tcp_listener_->stop();
- thread_io_service_->stop();
- thread_io_service_->restart();
- try {
- thread_io_service_->poll();
- } catch (...) {
- }
+ thread_io_service_->stopAndPoll();
thread_io_service_->stop();
// Get rid of the thread pool.
thread_io_service_.reset();
LOG_DEBUG(tcp_logger, isc::log::DBGLVL_TRACE_BASIC, MT_TCP_LISTENER_MGR_STOPPED)
- .arg(address_)
- .arg(port_);
+ .arg(address_)
+ .arg(port_);
}
bool
}
test_timer_.cancel();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
// Disable multi-threading.
MultiThreadingMgr::instance().setMode(false);
}
test_timer_.cancel();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief Create a new client.
IntervalTimer::ONE_SHOT);
}
io_service_->run();
- io_service_->stop();
- io_service_->restart();
- io_service_->poll();
+ io_service_->stopAndPoll(false);
}
/// @brief Filter that denies every other connection.
}
test_timer_.cancel();
- io_service_->stop();
- io_service_->restart();
- try {
- io_service_->poll();
- } catch (...) {
- }
+ io_service_->stopAndPoll();
}
/// @brief Fetch the server TLS context.
IntervalTimer::ONE_SHOT);
}
io_service_->run();
- io_service_->stop();
- io_service_->restart();
- io_service_->poll();
+ io_service_->stopAndPoll(false);
}
/// @brief Filter that denies every other connection.