Kea  1.5.0
io_service_signal.cc
Go to the documentation of this file.
1 // Copyright (C) 2014-2017 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 
10 #include <process/d_log.h>
12 
13 namespace isc {
14 namespace process {
15 
16 IOSignal::IOSignal (asiolink::IOService& io_service, int signum,
17  IOSignalHandler handler)
18  : sequence_id_(nextSequenceId()), signum_(signum),
19  timer_(new asiolink::IntervalTimer(io_service)) {
20  // Valid handler is essential.
21  if (!handler) {
23  "IOSignal - handler cannot be null");
24  }
25 
26  // Set up the timer as a one-shot which expires in 1 ms (intervals of 0
27  // are invalid). This means that once control returns to IOService::run
28  // the timer will have expired and its handler will be invoked.
29  timer_->setup(TimerCallback(sequence_id_, handler), 1,
31 }
32 
34  if (timer_) {
35  // In the unlikely event that the timer hasn't expired cancel it.
36  timer_->cancel();
37  }
38 }
39 
42  : sequence_id_(sequence_id), handler_(handler) {
43  if (!handler) {
45  "IOSignal::TimerCallback - handler cannot be null");
46  }
47 }
48 
49 void
51  try {
52  handler_(sequence_id_);
53  } catch (const std::exception& ex) {
54  // We log it and swallow it so we don't undermine IOService::run.
55  LOG_ERROR(dctl_logger, DCTL_SIGNAL_ERROR)
56  .arg(sequence_id_).arg(ex.what());
57  }
58 
59  return;
60 }
61 
63  : io_service_(io_service), signals_() {
64  if (!io_service_) {
65  isc_throw(IOSignalError, "IOSignalQueue - io_service cannot be NULL");
66  }
67 }
68 
70  clear();
71 }
72 
75  // Create the new signal.
76  IOSignalPtr signal(new IOSignal(*io_service_, signum, handler));
77 
78  // Make sure the sequence_id isn't already in the queue.
79  IOSignalId sequence_id = signal->getSequenceId();
80  IOSignalMap::iterator it = signals_.find(sequence_id);
81  if (it != signals_.end()) {
82  // This really shouldn't happen unless we are in the weeds.
83  isc_throw (IOSignalError, "pushSignal - "
84  "signal already exists for sequence_id: " << sequence_id);
85  }
86 
87  // Add the signal to the queue.
88  signals_[sequence_id] = signal;
89  return (sequence_id);
90 }
91 
94  // Look for the signal in the queue.
95  IOSignalMap::iterator it = signals_.find(sequence_id);
96  if (it == signals_.end()) {
97  // This really shouldn't happen unless we are in the weeds.
98  isc_throw (IOSignalError, "popSignal - "
99  "signal not found for sequence_id: " << sequence_id);
100  }
101 
102  // Save the signal so we can return it.
103  IOSignalPtr signal = ((*it).second);
104 
105  // Delete it from the queue.
106  signals_.erase(it);
107 
108  // Return the signal.
109  return (signal);
110 }
111 
112 void
114  signals_.clear();
115 }
116 
117 }; // end of isc::process namespace
118 }; // end of isc namespace
Exception thrown if IOSignal encounters an error.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition: macros.h:32
isc::log::Logger dctl_logger("dctl")
Defines the logger used within libkea-process library.
Definition: d_log.h:18
IOSignal(asiolink::IOService &io_service, int signum, IOSignalHandler handler)
Constructor.
IOSignalPtr popSignal(IOSignalId sequence_id)
Removes an IOSignal from the map and returns it.
boost::function< void(IOSignalId sequence_id)> IOSignalHandler
Defines a handler function for an IOSignal.
Defines the callback used by IOSignal's internal timer.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Implements an asynchronous "signal" for IOService driven processing.
TimerCallback(IOSignalId sequence_id, IOSignalHandler handler)
Constructor.
Defines the logger used by the top-level component of kea-dhcp-ddns.
void operator()()
() Operator which serves as the timer's callback
boost::shared_ptr< IOSignal > IOSignalPtr
Defines a pointer to an IOSignal.
void clear()
Erases the contents of the queue.
uint64_t IOSignalId
Defines a unique identifier type for IOSignal.
IOSignalId pushSignal(int signum, IOSignalHandler handler)
Creates an IOSignal.
IOSignalQueue(asiolink::IOServicePtr &io_service)
Constructor.