123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- // Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
- //
- // This Source Code Form is subject to the terms of the Mozilla Public
- // License, v. 2.0. If a copy of the MPL was not distributed with this
- // file, You can obtain one at http://mozilla.org/MPL/2.0/.
- #include <asiolink/interval_timer.h>
- #include <process/d_log.h>
- #include <process/io_service_signal.h>
- namespace isc {
- namespace process {
- IOSignal::IOSignal (asiolink::IOService& io_service, int signum,
- IOSignalHandler handler)
- : sequence_id_(nextSequenceId()), signum_(signum),
- timer_(new asiolink::IntervalTimer(io_service)) {
- // Valid handler is essential.
- if (!handler) {
- isc_throw(IOSignalError,
- "IOSignal - handler cannot be null");
- }
- // Set up the timer as a one-shot which expires in 1 ms (intervals of 0
- // are invalid). This means that once control returns to IOService::run
- // the timer will have expired and its handler will be invoked.
- timer_->setup(TimerCallback(sequence_id_, handler), 1,
- asiolink::IntervalTimer::ONE_SHOT);
- }
- IOSignal::~IOSignal() {
- if (timer_) {
- // In the unlikely event that the timer hasn't expired cancel it.
- timer_->cancel();
- }
- }
- IOSignal::
- TimerCallback::TimerCallback(IOSignalId sequence_id, IOSignalHandler handler)
- : sequence_id_(sequence_id), handler_(handler) {
- if (!handler) {
- isc_throw(IOSignalError,
- "IOSignal::TimerCallback - handler cannot be null");
- }
- }
- void
- IOSignal::TimerCallback::operator()() {
- try {
- handler_(sequence_id_);
- } catch (const std::exception& ex) {
- // We log it and swallow it so we don't undermine IOService::run.
- LOG_ERROR(dctl_logger, DCTL_SIGNAL_ERROR)
- .arg(sequence_id_).arg(ex.what());
- }
- return;
- }
- IOSignalQueue::IOSignalQueue(asiolink::IOServicePtr& io_service)
- : io_service_(io_service), signals_() {
- if (!io_service_) {
- isc_throw(IOSignalError, "IOSignalQueue - io_service cannot be NULL");
- }
- }
- IOSignalQueue::~IOSignalQueue() {
- clear();
- }
- IOSignalId
- IOSignalQueue::pushSignal(int signum, IOSignalHandler handler) {
- // Create the new signal.
- IOSignalPtr signal(new IOSignal(*io_service_, signum, handler));
- // Make sure the sequence_id isn't already in the queue.
- IOSignalId sequence_id = signal->getSequenceId();
- IOSignalMap::iterator it = signals_.find(sequence_id);
- if (it != signals_.end()) {
- // This really shouldn't happen unless we are in the weeds.
- isc_throw (IOSignalError, "pushSignal - "
- "signal already exists for sequence_id: " << sequence_id);
- }
- // Add the signal to the queue.
- signals_[sequence_id] = signal;
- return (sequence_id);
- }
- IOSignalPtr
- IOSignalQueue::popSignal(IOSignalId sequence_id) {
- // Look for the signal in the queue.
- IOSignalMap::iterator it = signals_.find(sequence_id);
- if (it == signals_.end()) {
- // This really shouldn't happen unless we are in the weeds.
- isc_throw (IOSignalError, "popSignal - "
- "signal not found for sequence_id: " << sequence_id);
- }
- // Save the signal so we can return it.
- IOSignalPtr signal = ((*it).second);
- // Delete it from the queue.
- signals_.erase(it);
- // Return the signal.
- return (signal);
- }
- void
- IOSignalQueue::clear() {
- signals_.clear();
- }
- }; // end of isc::process namespace
- }; // end of isc namespace
|