Hybrid ICN (hICN) plugin  v21.06-rc0-4-g18fa668
object_pool.h
1 /*
2  * Copyright (c) 2017-2019 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #pragma once
17 
18 #include <hicn/transport/utils/branch_prediction.h>
19 #include <hicn/transport/utils/spinlock.h>
20 
21 #include <deque>
22 #include <memory>
23 #include <mutex>
24 
25 namespace utils {
26 
27 template <typename T>
28 class ObjectPool {
29  class ObjectDeleter {
30  public:
31  ObjectDeleter(ObjectPool<T> *pool = nullptr) : pool_(pool) {}
32 
33  void operator()(T *t) {
34  if (pool_) {
35  pool_->add(t);
36  } else {
37  delete t;
38  }
39  }
40 
41  private:
42  ObjectPool<T> *pool_;
43  };
44 
45  public:
46  using Ptr = std::shared_ptr<T>;
47 
48  ObjectPool() : destructor_(false) {}
49 
50  // No copies
51  ObjectPool(const ObjectPool &other) = delete;
52 
53  ~ObjectPool() {
54  destructor_ = true;
55  for (auto &ptr : object_pool_) {
56  ptr.reset();
57  }
58  }
59 
60  bool empty() {
61  utils::SpinLock::Acquire locked(object_pool_lock_);
62  return object_pool_.empty();
63  }
64 
65  std::pair<bool, Ptr> get() {
66  utils::SpinLock::Acquire locked(object_pool_lock_);
67  if (object_pool_.empty()) {
68  return std::make_pair<bool, Ptr>(false, nullptr);
69  }
70 
71  auto ret = std::move(object_pool_.front());
72  object_pool_.pop_front();
73  return std::make_pair<bool, Ptr>(true, std::move(ret));
74  }
75 
76  void add(T *object) {
77  utils::SpinLock::Acquire locked(object_pool_lock_);
78 
79  if (TRANSPORT_EXPECT_TRUE(!destructor_)) {
80  object_pool_.emplace_front(makePtr(object));
81  } else {
82  delete object;
83  }
84  }
85 
86  Ptr makePtr(T *object) { return Ptr(object, ObjectDeleter(this)); }
87 
88  private:
89  utils::SpinLock object_pool_lock_;
90  std::deque<Ptr> object_pool_;
91  std::atomic<bool> destructor_;
92 };
93 
94 } // namespace utils
utils::SpinLock
Definition: spinlock.h:22
utils::SpinLock::Acquire
Definition: spinlock.h:24
utils::ObjectPool
Definition: object_pool.h:28