/usr/include/Poco/ObjectPool.h is in libpoco-dev 1.8.0.1-1ubuntu4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | //
// ObjectPool.h
//
// Library: Foundation
// Package: Core
// Module: ObjectPool
//
// Definition of the ObjectPool template class and friends.
//
// Copyright (c) 2010-2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Foundation_ObjectPool_INCLUDED
#define Foundation_ObjectPool_INCLUDED
#include "Poco/Poco.h"
#include "Poco/Mutex.h"
#include "Poco/Condition.h"
#include "Poco/AutoPtr.h"
#include "Poco/SharedPtr.h"
#include <vector>
#include <cctype>
namespace Poco {
template <class C, class P = C*>
class PoolableObjectFactory
/// A PoolableObjectFactory is responsible for creating and resetting
/// objects managed by an ObjectPool.
///
/// Together with an ObjectPool, a PoolableObjectFactory is used as
/// a policy class to change the behavior of the ObjectPool when
/// creating new objects, returning used objects back to the pool
/// and destroying objects, when the pool itself is destroyed or
/// shrunk.
{
public:
P createObject()
/// Create and return a new object.
{
return new C;
}
bool validateObject(P pObject)
/// Checks whether the object is still valid
/// and can be reused.
///
/// Returns true if the object is valid,
/// false otherwise.
///
/// To maintain the integrity of the pool, this method
/// must not throw an exception.
{
return true;
}
void activateObject(P pObject)
/// Called before an object is handed out by the pool.
/// Also called for newly created objects, before
/// they are given out for the first time.
{
}
void deactivateObject(P pObject)
/// Called after an object has been given back to the
/// pool and the object is still valid (a prior call
/// to validateObject() returned true).
///
/// To maintain the integrity of the pool, this method
/// must not throw an exception.
{
}
void destroyObject(P pObject)
/// Destroy an object.
///
/// To maintain the integrity of the pool, this method
/// must not throw an exception.
{
delete pObject;
}
};
template <class C>
class PoolableObjectFactory <C, Poco::AutoPtr<C> >
{
public:
Poco::AutoPtr<C> createObject()
{
return new C;
}
bool validateObject(Poco::AutoPtr<C> pObject)
{
return true;
}
void activateObject(Poco::AutoPtr<C> pObject)
{
}
void deactivateObject(Poco::AutoPtr<C> pObject)
{
}
void destroyObject(Poco::AutoPtr<C> pObject)
{
}
};
template <class C>
class PoolableObjectFactory <C, Poco::SharedPtr<C> >
{
public:
Poco::SharedPtr<C> createObject()
{
return new C;
}
bool validateObject(Poco::SharedPtr<C> pObject)
{
return true;
}
void activateObject(Poco::SharedPtr<C> pObject)
{
}
void deactivateObject(Poco::SharedPtr<C> pObject)
{
}
void destroyObject(Poco::SharedPtr<C> pObject)
{
}
};
template <class C, class P = C*, class F = PoolableObjectFactory<C, P> >
class ObjectPool
/// An ObjectPool manages a pool of objects of a certain class.
///
/// The number of objects managed by the pool can be restricted.
///
/// When an object is requested from the pool:
/// - If an object is available from the pool, an object from the pool is
/// removed from the pool, activated (using the factory) and returned.
/// - Otherwise, if the peak capacity of the pool has not yet been reached,
/// a new object is created and activated, using the object factory, and returned.
/// - If the peak capacity has already been reached, null is returned after timeout.
///
/// When an object is returned to the pool:
/// - If the object is valid (checked by calling validateObject()
/// from the object factory), the object is deactivated. If the
/// number of objects in the pool is below the capacity,
/// the object is added to the pool. Otherwise it is destroyed.
/// - If the object is not valid, it is destroyed immediately.
{
public:
ObjectPool(std::size_t capacity, std::size_t peakCapacity):
/// Creates a new ObjectPool with the given capacity
/// and peak capacity.
///
/// The PoolableObjectFactory must have a public default constructor.
_capacity(capacity),
_peakCapacity(peakCapacity),
_size(0)
{
poco_assert (capacity <= peakCapacity);
}
ObjectPool(const F& factory, std::size_t capacity, std::size_t peakCapacity):
/// Creates a new ObjectPool with the given PoolableObjectFactory,
/// capacity and peak capacity. The PoolableObjectFactory must have
/// a public copy constructor.
_factory(factory),
_capacity(capacity),
_peakCapacity(peakCapacity),
_size(0)
{
poco_assert (capacity <= peakCapacity);
}
~ObjectPool()
/// Destroys the ObjectPool.
{
try
{
for (typename std::vector<P>::iterator it = _pool.begin(); it != _pool.end(); ++it)
{
_factory.destroyObject(*it);
}
}
catch (...)
{
poco_unexpected();
}
}
P borrowObject(long timeoutMilliseconds = 0)
/// Obtains an object from the pool, or creates a new object if
/// possible.
///
/// Returns null if no object is available after timeout.
///
/// If activating the object fails, the object is destroyed and
/// the exception is passed on to the caller.
{
Poco::FastMutex::ScopedLock lock(_mutex);
if (!_pool.empty())
{
P pObject = _pool.back();
_pool.pop_back();
return activateObject(pObject);
}
if (_size >= _peakCapacity)
{
if (timeoutMilliseconds == 0)
{
return 0;
}
while (_size >= _peakCapacity)
{
if ( !_availableCondition.tryWait(_mutex, timeoutMilliseconds))
{
// timeout
return 0;
}
}
}
// _size < _peakCapacity
P pObject = _factory.createObject();
activateObject(pObject);
_size++;
return pObject;
}
void returnObject(P pObject)
/// Returns an object to the pool.
{
Poco::FastMutex::ScopedLock lock(_mutex);
if (_factory.validateObject(pObject))
{
_factory.deactivateObject(pObject);
if (_pool.size() < _capacity)
{
try
{
_pool.push_back(pObject);
return;
}
catch (...)
{
}
}
}
_factory.destroyObject(pObject);
_size--;
_availableCondition.signal();
}
std::size_t capacity() const
{
return _capacity;
}
std::size_t peakCapacity() const
{
return _peakCapacity;
}
std::size_t size() const
{
Poco::FastMutex::ScopedLock lock(_mutex);
return _size;
}
std::size_t available() const
{
Poco::FastMutex::ScopedLock lock(_mutex);
return _pool.size() + _peakCapacity - _size;
}
protected:
P activateObject(P pObject)
{
try
{
_factory.activateObject(pObject);
}
catch (...)
{
_factory.destroyObject(pObject);
throw;
}
return pObject;
}
private:
ObjectPool();
ObjectPool(const ObjectPool&);
ObjectPool& operator = (const ObjectPool&);
F _factory;
std::size_t _capacity;
std::size_t _peakCapacity;
std::size_t _size;
std::vector<P> _pool;
mutable Poco::FastMutex _mutex;
Poco::Condition _availableCondition;
};
} // namespace Poco
#endif // Foundation_ObjectPool_INCLUDED
|