CMS 3D CMS Logo

ReusableObjectHolder.h
Go to the documentation of this file.
1 #ifndef FWCore_Utilities_ReusableObjectHolder_h
2 #define FWCore_Utilities_ReusableObjectHolder_h
3 
4 // -*- C++ -*-
5 //
6 // Package: FWCore/Utilities
7 // Class : ReusableObjectHolder
8 //
67 //
68 // Original Author: Chris Jones
69 // Created: Fri, 31 July 2014 14:29:41 GMT
70 //
71 
72 #include <memory>
73 #include <cassert>
74 #include <atomic>
75 #include "tbb/task.h"
76 #include "tbb/concurrent_queue.h"
77 
78 namespace edm {
79  template <class T, class Deleter = std::default_delete<T>>
81  public:
82  using deleter_type = Deleter;
83 
87  assert(0 == iOther.m_outstandingObjects);
88  }
90  assert(0 == m_outstandingObjects);
91  std::unique_ptr<T, Deleter> item;
92  while (m_availableQueue.try_pop(item)) {
93  item.reset();
94  }
95  }
96 
100  void add(std::unique_ptr<T, Deleter> iItem) {
101  if (nullptr != iItem) {
102  m_availableQueue.push(std::move(iItem));
103  }
104  }
105 
109  std::shared_ptr<T> tryToGet() {
110  std::unique_ptr<T, Deleter> item;
111  m_availableQueue.try_pop(item);
112  if (nullptr == item) {
113  return std::shared_ptr<T>{};
114  }
115  //instead of deleting, hand back to queue
116  auto pHolder = this;
117  auto deleter = item.get_deleter();
119  return std::shared_ptr<T>{item.release(), [pHolder, deleter](T* iItem) {
120  pHolder->addBack(std::unique_ptr<T, Deleter>{iItem, deleter});
121  }};
122  }
123 
125  template <typename F>
126  std::shared_ptr<T> makeOrGet(F iFunc) {
127  std::shared_ptr<T> returnValue;
128  while (!(returnValue = tryToGet())) {
129  add(makeUnique(iFunc()));
130  }
131  return returnValue;
132  }
133 
137  template <typename FM, typename FC>
138  std::shared_ptr<T> makeOrGetAndClear(FM iMakeFunc, FC iClearFunc) {
139  std::shared_ptr<T> returnValue;
140  while (!(returnValue = tryToGet())) {
141  add(makeUnique(iMakeFunc()));
142  }
143  iClearFunc(returnValue.get());
144  return returnValue;
145  }
146 
147  private:
148  std::unique_ptr<T> makeUnique(T* ptr) {
149  static_assert(std::is_same_v<Deleter, std::default_delete<T>>,
150  "Generating functions returning raw pointers are supported only with std::default_delete<T>");
151  return std::unique_ptr<T>{ptr};
152  }
153 
154  std::unique_ptr<T, Deleter> makeUnique(std::unique_ptr<T, Deleter> ptr) { return ptr; }
155 
156  void addBack(std::unique_ptr<T, Deleter> iItem) {
157  m_availableQueue.push(std::move(iItem));
159  }
160 
161  tbb::concurrent_queue<std::unique_ptr<T, Deleter>> m_availableQueue;
162  std::atomic<size_t> m_outstandingObjects;
163  };
164 
165 } // namespace edm
166 
167 #endif /* end of include guard: FWCore_Utilities_ReusableObjectHolder_h */
std::default_delete< edm::ESProductHost > deleter_type
tbb::concurrent_queue< std::unique_ptr< T, Deleter > > m_availableQueue
std::unique_ptr< T > makeUnique(T *ptr)
void add(std::unique_ptr< T, Deleter > iItem)
void addBack(std::unique_ptr< T, Deleter > iItem)
std::atomic< size_t > m_outstandingObjects
std::shared_ptr< T > makeOrGetAndClear(FM iMakeFunc, FC iClearFunc)
std::unique_ptr< T, Deleter > makeUnique(std::unique_ptr< T, Deleter > ptr)
std::shared_ptr< T > makeOrGet(F iFunc)
If there isn&#39;t an object already available, creates a new one using iFunc.
std::shared_ptr< T > tryToGet()
ReusableObjectHolder(ReusableObjectHolder &&iOther)
HLT enums.
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163
long double T
def move(src, dest)
Definition: eostools.py:511