Kea  1.5.0
parking_lots.h
Go to the documentation of this file.
1 // Copyright (C) 2018 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 #ifndef PARKING_LOTS_H
8 #define PARKING_LOTS_H
9 
10 #include <exceptions/exceptions.h>
11 #include <boost/any.hpp>
12 #include <boost/make_shared.hpp>
13 #include <boost/shared_ptr.hpp>
14 #include <functional>
15 #include <list>
16 #include <map>
17 
18 #include <iostream>
19 
20 namespace isc {
21 namespace hooks {
22 
60 class ParkingLot {
61 public:
62 
71  template<typename T>
72  void park(T parked_object, std::function<void()> unpark_callback) {
73  auto it = find(parked_object);
74  if (it == parking_.end() || it->refcount_ <= 0) {
75  isc_throw(InvalidOperation, "unable to park an object because"
76  " reference count for this object hasn't been increased."
77  " Call ParkingLot::reference() first");
78  } else {
79  it->update(parked_object, unpark_callback);
80  }
81  }
82 
91  template<typename T>
92  void reference(T parked_object) {
93  auto it = find(parked_object);
94  if (it == parking_.end()) {
95  ParkingInfo parking_info(parked_object);
96  parking_.push_back(parking_info);
97 
98  } else {
99  ++it->refcount_;
100  }
101  }
102 
116  template<typename T>
117  bool unpark(T parked_object, bool force = false) {
118  auto it = find(parked_object);
119  if (it != parking_.end()) {
120  if (force) {
121  it->refcount_ = 0;
122 
123  } else {
124  --it->refcount_;
125  }
126 
127  if (it->refcount_ <= 0) {
128  // Unpark the packet and invoke the callback.
129  std::function<void()> cb = it->unpark_callback_;
130  parking_.erase(it);
131  cb();
132  }
133 
134  // Parked object found, so return true to indicate that the
135  // operation was successful. It doesn't necessarily mean
136  // that the object was unparked, but at least the reference
137  // count was decreased.
138  return (true);
139  }
140 
141  // No such parked object.
142  return (false);
143  }
144 
151  template<typename T>
152  bool drop(T parked_object) {
153  auto it = find(parked_object);
154  if (it != parking_.end()) {
155  // Parked object found.
156  parking_.erase(it);
157  return (true);
158  }
159 
160  // No such object.
161  return (false);
162  }
163 
164 private:
165 
167  struct ParkingInfo {
168  boost::any parked_object_;
169  std::function<void()> unpark_callback_;
170  int refcount_;
171 
176  ParkingInfo(const boost::any& parked_object,
177  std::function<void()> callback = 0)
178  : parked_object_(parked_object), unpark_callback_(callback),
179  refcount_(1) {
180  }
181 
186  void update(const boost::any& parked_object,
187  std::function<void()> callback) {
188  parked_object_ = parked_object;
189  unpark_callback_ = callback;
190  }
191  };
192 
194  typedef std::list<ParkingInfo> ParkingInfoList;
196  typedef ParkingInfoList::iterator ParkingInfoListIterator;
197 
199  ParkingInfoList parking_;
200 
207  template<typename T>
208  ParkingInfoListIterator find(T parked_object) {
209  for (auto it = parking_.begin(); it != parking_.end(); ++it) {
210  if (boost::any_cast<T>(it->parked_object_) == parked_object) {
211  return (it);
212  }
213  }
214  return (parking_.end());
215  }
216 };
217 
219 typedef boost::shared_ptr<ParkingLot> ParkingLotPtr;
220 
232 public:
233 
238  ParkingLotHandle(const ParkingLotPtr& parking_lot)
239  : parking_lot_(parking_lot) {
240  }
241 
250  template<typename T>
251  void reference(T parked_object) {
252  parking_lot_->reference(parked_object);
253  }
254 
266  template<typename T>
267  bool unpark(T parked_object) {
268  return (parking_lot_->unpark(parked_object));
269  }
270 
279  template<typename T>
280  bool drop(T parked_object) {
281  return (parking_lot_->drop(parked_object));
282  }
283 
284 private:
285 
287  ParkingLotPtr parking_lot_;
288 
289 };
290 
292 typedef boost::shared_ptr<ParkingLotHandle> ParkingLotHandlePtr;
293 
295 class ParkingLots {
296 public:
297 
301  void clear() {
302  parking_lots_.clear();
303  }
304 
313  ParkingLotPtr getParkingLotPtr(const int hook_index) {
314  if (parking_lots_.count(hook_index) == 0) {
315  parking_lots_[hook_index] = boost::make_shared<ParkingLot>();
316  }
317  return (parking_lots_[hook_index]);
318  }
319 
320 private:
321 
323  std::map<int, ParkingLotPtr> parking_lots_;
324 
325 };
326 
328 typedef boost::shared_ptr<ParkingLots> ParkingLotsPtr;
329 
330 } // end of namespace hooks
331 } // end of namespace isc
332 
333 #endif
isc::hooks::ParkingLot
Parking lot for objects, e.g.
Definition: parking_lots.h:60
isc::hooks::ParkingLot::park
void park(T parked_object, std::function< void()> unpark_callback)
Parks an object.
Definition: parking_lots.h:72
isc::hooks::ParkingLot::drop
bool drop(T parked_object)
Removes parked object without calling a callback.
Definition: parking_lots.h:152
isc::hooks::ParkingLotsPtr
boost::shared_ptr< ParkingLots > ParkingLotsPtr
Type of the pointer to the parking lots.
Definition: parking_lots.h:328
isc::hooks::ParkingLotHandle::ParkingLotHandle
ParkingLotHandle(const ParkingLotPtr &parking_lot)
Constructor.
Definition: parking_lots.h:238
isc::hooks::ParkingLots::clear
void clear()
Removes all parked objects.
Definition: parking_lots.h:301
isc::hooks::ParkingLotHandlePtr
boost::shared_ptr< ParkingLotHandle > ParkingLotHandlePtr
Pointer to the parking lot handle.
Definition: parking_lots.h:292
isc
Defines the logger used by the top-level component of kea-dhcp-ddns.
Definition: agent_parser.cc:144
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition: exceptions/exceptions.h:192
isc::InvalidOperation
A generic exception that is thrown if a function is called in a prohibited way.
Definition: exceptions/exceptions.h:143
isc::hooks::ParkingLots::getParkingLotPtr
ParkingLotPtr getParkingLotPtr(const int hook_index)
Returns pointer to the parking lot for a hook points.
Definition: parking_lots.h:313
isc::hooks::ParkingLotHandle::reference
void reference(T parked_object)
Increases reference counter for the parked object.
Definition: parking_lots.h:251
isc::hooks::ParkingLotPtr
boost::shared_ptr< ParkingLot > ParkingLotPtr
Type of the pointer to the parking lot.
Definition: parking_lots.h:219
exceptions.h
isc::hooks::ParkingLot::unpark
bool unpark(T parked_object, bool force=false)
Signals that the object should be unparked.
Definition: parking_lots.h:117
isc::hooks::ParkingLotHandle
Provides a limited view to the ParkingLot.
Definition: parking_lots.h:231
isc::hooks::ParkingLotHandle::drop
bool drop(T parked_object)
Removes parked object without calling a callback.
Definition: parking_lots.h:280
isc::hooks::ParkingLotHandle::unpark
bool unpark(T parked_object)
Signals that the object should be unparked.
Definition: parking_lots.h:267
isc::hooks::ParkingLots
Collection of parking lots for various hook points.
Definition: parking_lots.h:295
isc::hooks::ParkingLot::reference
void reference(T parked_object)
Increases reference counter for the parked object.
Definition: parking_lots.h:92