summaryrefslogtreecommitdiffstats
path: root/src/lib/dhcpsrv/timer_mgr.cc
diff options
context:
space:
mode:
authorMarcin Siodelski <marcin@isc.org>2015-09-04 11:01:48 +0200
committerMarcin Siodelski <marcin@isc.org>2015-09-04 11:01:48 +0200
commit79d70c0695ce4beb03237ce91ea3cbcce0d07588 (patch)
treef3b5b72044bffb5e14ab7768ef1dcaa1b8015947 /src/lib/dhcpsrv/timer_mgr.cc
parent[3970] Addressed most of the review comments. (diff)
downloadkea-79d70c0695ce4beb03237ce91ea3cbcce0d07588.tar.xz
kea-79d70c0695ce4beb03237ce91ea3cbcce0d07588.zip
[3970] Add parameter to run pending callbacks when thread is stopped.
Diffstat (limited to 'src/lib/dhcpsrv/timer_mgr.cc')
-rw-r--r--src/lib/dhcpsrv/timer_mgr.cc46
1 files changed, 27 insertions, 19 deletions
diff --git a/src/lib/dhcpsrv/timer_mgr.cc b/src/lib/dhcpsrv/timer_mgr.cc
index 841dad282e..9fe5da1803 100644
--- a/src/lib/dhcpsrv/timer_mgr.cc
+++ b/src/lib/dhcpsrv/timer_mgr.cc
@@ -212,7 +212,7 @@ TimerMgr::startThread() {
}
void
-TimerMgr::stopThread() {
+TimerMgr::stopThread(const bool run_pending_callbacks) {
// If thread is not running, this is no-op.
if (thread_) {
// Only log it if we really have something to stop.
@@ -222,11 +222,12 @@ TimerMgr::stopThread() {
// Stop the IO Service. This will break the IOService::run executed in the
// worker thread. The thread will now terminate.
getIOService().stop();
- // When the worker thread may be waiting on the call to
- // WatchSocket::markReady until main thread clears the socket.
- // To unblock the thread we have to clear all sockets to make
- // sure that the thread doesn't remain blocked.
- clearReadySockets();
+ // Some of the watch sockets may be already marked as ready and
+ // have some pending callbacks to be executed. If the caller
+ // wants us to run the callbacks we clear the sockets and run
+ // them. If pending callbacks shouldn't be executed, this will
+ // only clear the sockets (which should be substantially faster).
+ clearReadySockets(run_pending_callbacks);
// Wait for the thread to terminate.
thread_->wait();
// Set the thread pointer to NULL to indicate that the thread is not running.
@@ -241,7 +242,6 @@ TimerMgr::getIOService() const {
return (*io_service_);
}
-
void
TimerMgr::timerCallback(const std::string& timer_name) {
// Find the specified timer setup.
@@ -260,7 +260,6 @@ TimerMgr::ifaceMgrCallback(const std::string& timer_name) {
// Find the specified timer setup.
TimerInfoMap::iterator timer_info_it = registered_timers_.find(timer_name);
if (timer_info_it != registered_timers_.end()) {
- const TimerInfoPtr& timer_info = timer_info_it->second;
// We're executing a callback function from the Interface Manager.
// This callback function is executed when the call to select() is
// interrupted as a result of receiving some data over the watch
@@ -268,25 +267,34 @@ TimerMgr::ifaceMgrCallback(const std::string& timer_name) {
// ready. Then execute the callback function supplied by the
// TimerMgr user to perform custom actions on the expiration of
// the given timer.
- timer_info->watch_socket_.clearReady();
-
- // Running user-defined operation for the timer. Logging it
- // on the slightly lower debug level as there may be many
- // such traces.
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
- DHCPSRV_TIMERMGR_RUN_TIMER_OPERATION)
- .arg(timer_name);
- timer_info->user_callback_();
+ handleReadySocket(timer_info_it, true);
}
}
void
-TimerMgr::clearReadySockets() {
+TimerMgr::clearReadySockets(const bool run_pending_callbacks) {
for (TimerInfoMap::iterator timer_info_it = registered_timers_.begin();
timer_info_it != registered_timers_.end(); ++timer_info_it) {
- timer_info_it->second->watch_socket_.clearReady();
+ handleReadySocket(timer_info_it, run_pending_callbacks);
}
}
+template<typename Iterator>
+void
+TimerMgr::handleReadySocket(Iterator timer_info_iterator,
+ const bool run_callback) {
+ timer_info_iterator->second->watch_socket_.clearReady();
+
+ if (run_callback) {
+ // Running user-defined operation for the timer. Logging it
+ // on the slightly lower debug level as there may be many
+ // such traces.
+ LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
+ DHCPSRV_TIMERMGR_RUN_TIMER_OPERATION)
+ .arg(timer_info_iterator->first);
+ timer_info_iterator->second->user_callback_();
+ }
+}
+
} // end of namespace isc::dhcp
} // end of namespace isc