#3019: ObjectPool wait on borrow condition fix

This commit is contained in:
Günter Obiltschnig
2021-06-15 13:30:51 +02:00
parent ea455ad891
commit 01720ce82b
3 changed files with 68 additions and 41 deletions

View File

@@ -217,22 +217,15 @@ public:
{ {
Poco::FastMutex::ScopedLock lock(_mutex); Poco::FastMutex::ScopedLock lock(_mutex);
if (!_pool.empty()) if (_size >= _peakCapacity && _pool.empty())
{
P pObject = _pool.back();
_pool.pop_back();
return activateObject(pObject);
}
if (_size >= _peakCapacity)
{ {
if (timeoutMilliseconds == 0) if (timeoutMilliseconds == 0)
{ {
return 0; return 0;
} }
while (_size >= _peakCapacity) while (_size >= _peakCapacity && _pool.empty())
{ {
if ( !_availableCondition.tryWait(_mutex, timeoutMilliseconds)) if (!_availableCondition.tryWait(_mutex, timeoutMilliseconds))
{ {
// timeout // timeout
return 0; return 0;
@@ -240,10 +233,19 @@ public:
} }
} }
if (!_pool.empty())
{
P pObject = _pool.back();
_pool.pop_back();
return activateObject(pObject);
}
// _size < _peakCapacity // _size < _peakCapacity
P pObject = _factory.createObject(); P pObject = _factory.createObject();
activateObject(pObject); activateObject(pObject);
_size++; _size++;
return pObject; return pObject;
} }
@@ -260,6 +262,7 @@ public:
try try
{ {
_pool.push_back(pObject); _pool.push_back(pObject);
_availableCondition.signal();
return; return;
} }
catch (...) catch (...)

View File

@@ -13,6 +13,7 @@
#include "CppUnit/TestSuite.h" #include "CppUnit/TestSuite.h"
#include "Poco/ObjectPool.h" #include "Poco/ObjectPool.h"
#include "Poco/Exception.h" #include "Poco/Exception.h"
#include "Poco/Thread.h"
using Poco::ObjectPool; using Poco::ObjectPool;
@@ -30,7 +31,7 @@ ObjectPoolTest::~ObjectPoolTest()
void ObjectPoolTest::testObjectPool() void ObjectPoolTest::testObjectPool()
{ {
ObjectPool<std::string, Poco::SharedPtr<std::string> > pool(3, 4); ObjectPool<std::string, Poco::SharedPtr<std::string>> pool(3, 4);
assertTrue (pool.capacity() == 3); assertTrue (pool.capacity() == 3);
assertTrue (pool.peakCapacity() == 4); assertTrue (pool.peakCapacity() == 4);
@@ -88,6 +89,27 @@ void ObjectPoolTest::testObjectPool()
} }
void ObjectPoolTest::testObjectPoolWaitOnBorrowObject()
{
ObjectPool<std::string, Poco::SharedPtr<std::string>> pool(1, 1);
Poco::SharedPtr<std::string> objectToReturnDuringBorrow = pool.borrowObject();
Poco::Thread threadToReturnObject;
threadToReturnObject.startFunc(
[&pool, &objectToReturnDuringBorrow]()
{
pool.returnObject(objectToReturnDuringBorrow);
}
);
Poco::SharedPtr<std::string> object = pool.borrowObject(1000);
threadToReturnObject.join();
assertFalse(object.isNull());
}
void ObjectPoolTest::setUp() void ObjectPoolTest::setUp()
{ {
} }
@@ -103,6 +125,7 @@ CppUnit::Test* ObjectPoolTest::suite()
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("ObjectPoolTest"); CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("ObjectPoolTest");
CppUnit_addTest(pSuite, ObjectPoolTest, testObjectPool); CppUnit_addTest(pSuite, ObjectPoolTest, testObjectPool);
CppUnit_addTest(pSuite, ObjectPoolTest, testObjectPoolWaitOnBorrowObject);
return pSuite; return pSuite;
} }

View File

@@ -25,6 +25,7 @@ public:
~ObjectPoolTest(); ~ObjectPoolTest();
void testObjectPool(); void testObjectPool();
void testObjectPoolWaitOnBorrowObject();
void setUp(); void setUp();
void tearDown(); void tearDown();