Kea 1.9.11
parking_lots.h
Go to the documentation of this file.
1// Copyright (C) 2018-2021 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
15#include <functional>
16#include <iostream>
17#include <sstream>
18#include <list>
19#include <unordered_map>
20#include <mutex>
21#include <thread>
22
23namespace isc {
24namespace hooks {
25
74public:
82 template<typename T>
83 void park(T parked_object, std::function<void()> unpark_callback) {
84 std::lock_guard<std::mutex> lock(mutex_);
85 auto it = find(parked_object);
86 if (it != parking_.end()) {
87 isc_throw(InvalidOperation, "object is already parked!");
88 }
89
90 // Add the object to the parking lot. At this point refcount = 0.
91 ParkingInfo pinfo(parked_object, unpark_callback);
92 parking_[makeKey(parked_object)] = pinfo;
93 }
94
104 template<typename T>
105 int reference(T parked_object) {
106 std::lock_guard<std::mutex> lock(mutex_);
107 auto it = find(parked_object);
108 if (it == parking_.end()) {
109 isc_throw(InvalidOperation, "cannot reference an object"
110 " that has not been parked.");
111 }
112
113 // Bump and return the reference count
114 return (++it->second.refcount_);
115 }
116
125 template<typename T>
126 int dereference(T parked_object) {
127 std::lock_guard<std::mutex> lock(mutex_);
128 auto it = find(parked_object);
129 if (it == parking_.end()) {
130 isc_throw(InvalidOperation, "cannot dereference an object"
131 " that has not been parked.");
132 }
133
134 // Decrement and return the reference count.
135 return (--it->second.refcount_);
136 }
137
151 template<typename T>
152 bool unpark(T parked_object, bool force = false) {
153 // Initialize as the empty function.
154 std::function<void()> cb;
155 {
156 std::lock_guard<std::mutex> lock(mutex_);
157 auto it = find(parked_object);
158 if (it == parking_.end()) {
159 // No such parked object.
160 return (false);
161 }
162
163 if (force) {
164 it->second.refcount_ = 0;
165 } else {
166 --it->second.refcount_;
167 }
168
169 if (it->second.refcount_ <= 0) {
170 // Unpark the packet and set the callback.
171 cb = it->second.unpark_callback_;
172 parking_.erase(it);
173 }
174 }
175
176 // Invoke the callback if not empty.
177 if (cb) {
178 cb();
179 }
180
181 // Parked object found, so return true to indicate that the
182 // operation was successful. It doesn't necessarily mean
183 // that the object was unparked, but at least the reference
184 // count was decreased.
185 return (true);
186 }
187
194 template<typename T>
195 bool drop(T parked_object) {
196 std::lock_guard<std::mutex> lock(mutex_);
197 auto it = find(parked_object);
198 if (it != parking_.end()) {
199 // Parked object found.
200 parking_.erase(it);
201 return (true);
202 }
203
204 // No such object.
205 return (false);
206 }
207
208public:
209
211 struct ParkingInfo {
213 boost::any parked_object_;
214
216 std::function<void()> unpark_callback_;
217
220
225
230 ParkingInfo(const boost::any& parked_object,
231 std::function<void()> callback = 0)
232 : parked_object_(parked_object), unpark_callback_(callback),
233 refcount_(0) {}
234
239 void update(const boost::any& parked_object,
240 std::function<void()> callback) {
241 parked_object_ = parked_object;
242 unpark_callback_ = callback;
243 }
244 };
245
246private:
247
249 typedef std::unordered_map<std::string, ParkingInfo> ParkingInfoList;
250
252 typedef ParkingInfoList::iterator ParkingInfoListIterator;
253
255 ParkingInfoList parking_;
256
262 template<typename T>
263 std::string makeKey(T parked_object) {
264 std::stringstream ss;
265 ss << boost::any_cast<T>(parked_object);
266 return (ss.str());
267 }
268
275 template<typename T>
276 ParkingInfoListIterator find(T parked_object) {
277 return (parking_.find(makeKey(parked_object)));
278 }
279
284 std::mutex mutex_;
285};
286
288typedef boost::shared_ptr<ParkingLot> ParkingLotPtr;
289
301public:
302
307 ParkingLotHandle(const ParkingLotPtr& parking_lot)
308 : parking_lot_(parking_lot) {
309 }
310
320 template<typename T>
321 int reference(T parked_object) {
322 return (parking_lot_->reference(parked_object));
323 }
324
333 template<typename T>
334 int dereference(T parked_object) {
335 return (parking_lot_->dereference(parked_object));
336 }
337
349 template<typename T>
350 bool unpark(T parked_object) {
351 return (parking_lot_->unpark(parked_object));
352 }
353
362 template<typename T>
363 bool drop(T parked_object) {
364 return (parking_lot_->drop(parked_object));
365 }
366
367private:
368
370 ParkingLotPtr parking_lot_;
371
372};
373
375typedef boost::shared_ptr<ParkingLotHandle> ParkingLotHandlePtr;
376
379public:
380
384 void clear() {
385 std::lock_guard<std::mutex> lock(mutex_);
386 parking_lots_.clear();
387 }
388
397 ParkingLotPtr getParkingLotPtr(const int hook_index) {
398 std::lock_guard<std::mutex> lock(mutex_);
399 if (parking_lots_.count(hook_index) == 0) {
400 parking_lots_[hook_index] = boost::make_shared<ParkingLot>();
401 }
402 return (parking_lots_[hook_index]);
403 }
404
405private:
406
408 std::unordered_map<int, ParkingLotPtr> parking_lots_;
409
411 std::mutex mutex_;
412};
413
415typedef boost::shared_ptr<ParkingLots> ParkingLotsPtr;
416
417} // end of namespace hooks
418} // end of namespace isc
419
420#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:300
bool drop(T parked_object)
Removes parked object without calling a callback.
Definition: parking_lots.h:363
bool unpark(T parked_object)
Signals that the object should be unparked.
Definition: parking_lots.h:350
int reference(T parked_object)
Increases reference counter for the parked object.
Definition: parking_lots.h:321
int dereference(T parked_object)
Decreases the reference counter for the parked object.
Definition: parking_lots.h:334
ParkingLotHandle(const ParkingLotPtr &parking_lot)
Constructor.
Definition: parking_lots.h:307
Parking lot for objects, e.g.
Definition: parking_lots.h:73
bool unpark(T parked_object, bool force=false)
Signals that the object should be unparked.
Definition: parking_lots.h:152
bool drop(T parked_object)
Removes parked object without calling a callback.
Definition: parking_lots.h:195
int dereference(T parked_object)
Decreases the reference counter for the parked object.
Definition: parking_lots.h:126
int reference(T parked_object)
Increases reference counter for the parked object.
Definition: parking_lots.h:105
void park(T parked_object, std::function< void()> unpark_callback)
Parks an object.
Definition: parking_lots.h:83
Collection of parking lots for various hook points.
Definition: parking_lots.h:378
ParkingLotPtr getParkingLotPtr(const int hook_index)
Returns pointer to the parking lot for a hook points.
Definition: parking_lots.h:397
void clear()
Removes all parked objects.
Definition: parking_lots.h:384
#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:415
boost::shared_ptr< ParkingLotHandle > ParkingLotHandlePtr
Pointer to the parking lot handle.
Definition: parking_lots.h:375
boost::shared_ptr< ParkingLot > ParkingLotPtr
Type of the pointer to the parking lot.
Definition: parking_lots.h:288
Defines the logger used by the top-level component of kea-lfc.
Holds information about parked object.
Definition: parking_lots.h:211
int refcount_
The current reference count.
Definition: parking_lots.h:219
boost::any parked_object_
The parked object.
Definition: parking_lots.h:213
void update(const boost::any &parked_object, std::function< void()> callback)
Update parking information.
Definition: parking_lots.h:239
ParkingInfo(const boost::any &parked_object, std::function< void()> callback=0)
Constructor.
Definition: parking_lots.h:230
std::function< void()> unpark_callback_
The pointer to callback.
Definition: parking_lots.h:216