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
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
20namespace isc {
21namespace hooks {
22
61public:
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
164private:
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
219typedef boost::shared_ptr<ParkingLot> ParkingLotPtr;
220
232public:
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
284private:
285
287 ParkingLotPtr parking_lot_;
288
289};
290
292typedef boost::shared_ptr<ParkingLotHandle> ParkingLotHandlePtr;
293
296public:
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
320private:
321
323 std::map<int, ParkingLotPtr> parking_lots_;
324
325};
326
328typedef boost::shared_ptr<ParkingLots> ParkingLotsPtr;
329
330} // end of namespace hooks
331} // end of namespace isc
332
333#endif
A generic exception that is thrown if a function is called in a prohibited way.
Provides a limited view to the ParkingLot.
Definition: parking_lots.h:231
bool drop(T parked_object)
Removes parked object without calling a callback.
Definition: parking_lots.h:280
bool unpark(T parked_object)
Signals that the object should be unparked.
Definition: parking_lots.h:267
void reference(T parked_object)
Increases reference counter for the parked object.
Definition: parking_lots.h:251
ParkingLotHandle(const ParkingLotPtr &parking_lot)
Constructor.
Definition: parking_lots.h:238
Parking lot for objects, e.g.
Definition: parking_lots.h:60
bool unpark(T parked_object, bool force=false)
Signals that the object should be unparked.
Definition: parking_lots.h:117
bool drop(T parked_object)
Removes parked object without calling a callback.
Definition: parking_lots.h:152
void reference(T parked_object)
Increases reference counter for the parked object.
Definition: parking_lots.h:92
void park(T parked_object, std::function< void()> unpark_callback)
Parks an object.
Definition: parking_lots.h:72
Collection of parking lots for various hook points.
Definition: parking_lots.h:295
ParkingLotPtr getParkingLotPtr(const int hook_index)
Returns pointer to the parking lot for a hook points.
Definition: parking_lots.h:313
void clear()
Removes all parked objects.
Definition: parking_lots.h:301
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< ParkingLots > ParkingLotsPtr
Type of the pointer to the parking lots.
Definition: parking_lots.h:328
boost::shared_ptr< ParkingLotHandle > ParkingLotHandlePtr
Pointer to the parking lot handle.
Definition: parking_lots.h:292
boost::shared_ptr< ParkingLot > ParkingLotPtr
Type of the pointer to the parking lot.
Definition: parking_lots.h:219
Defines the logger used by the top-level component of kea-dhcp-ddns.