From ad8fb867c51daa6eb2888f6a6af3bb51b5f91cd3 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 23 Dec 2015 17:23:02 +0000 Subject: Add some missing features to resource handle for early release and reassignment --- libadhocutil/resourcePool.h | 4 ++++ libadhocutil/resourcePool.impl.h | 35 ++++++++++++++++++++++++++++- libadhocutil/unittests/testResourcePool.cpp | 17 +++++++++++++- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/libadhocutil/resourcePool.h b/libadhocutil/resourcePool.h index 5ccb516..f77f2a5 100644 --- a/libadhocutil/resourcePool.h +++ b/libadhocutil/resourcePool.h @@ -34,6 +34,10 @@ namespace AdHoc { Resource * operator->() const; /// Access to the resource. Resource * get() const; + /// Release the resource back to the pool. + void release(); + /// Cast to bool. + operator bool() const; /// Get number of handles to this resource. unsigned int handleCount() const; diff --git a/libadhocutil/resourcePool.impl.h b/libadhocutil/resourcePool.impl.h index 85a6d3d..269cd00 100644 --- a/libadhocutil/resourcePool.impl.h +++ b/libadhocutil/resourcePool.impl.h @@ -5,6 +5,8 @@ #include "lockHelpers.h" #include "safeMapFind.h" +#define ASSERT(expr) if(!expr) throw std::runtime_error(#expr) + namespace AdHoc { // // ResourceHandle @@ -27,13 +29,16 @@ namespace AdHoc { template ResourceHandle::~ResourceHandle() { - decRef(); + if (resource) { + decRef(); + } } template unsigned int ResourceHandle::handleCount() const { + ASSERT(resource); return boost::get<2>(*resource); } @@ -41,20 +46,47 @@ namespace AdHoc { R * ResourceHandle::get() const { + ASSERT(resource); return boost::get<0>(*resource); } + template + void + ResourceHandle::release() + { + decRef(); + } + + template + ResourceHandle::operator bool() const + { + return resource; + } + template R * ResourceHandle::operator->() const { + ASSERT(resource); return boost::get<0>(*resource); } + template + void + ResourceHandle::operator=(const ResourceHandle & rh) + { + if (resource) { + decRef(); + } + resource = rh.resource; + incRef(); + } + template void ResourceHandle::incRef() const { + ASSERT(resource); ++boost::get<2>(*resource); } @@ -62,6 +94,7 @@ namespace AdHoc { void ResourceHandle::decRef() { + ASSERT(resource); if (!--boost::get<2>(*resource)) { if (std::uncaught_exception()) { boost::get<1>(*resource)->discard(boost::get<0>(*resource)); diff --git a/libadhocutil/unittests/testResourcePool.cpp b/libadhocutil/unittests/testResourcePool.cpp index 349ea00..411f1bb 100644 --- a/libadhocutil/unittests/testResourcePool.cpp +++ b/libadhocutil/unittests/testResourcePool.cpp @@ -58,7 +58,8 @@ BOOST_AUTO_TEST_CASE ( get ) BOOST_REQUIRE_EQUAL(2, MockResource::count); BOOST_REQUIRE(r2.get()); - auto r1a = r1; + auto r1a = r2; + r1a = r1; BOOST_REQUIRE_EQUAL(2, pool.inUseCount()); BOOST_REQUIRE_EQUAL(0, pool.availableCount()); BOOST_REQUIRE_EQUAL(2, r1.handleCount()); @@ -67,6 +68,20 @@ BOOST_AUTO_TEST_CASE ( get ) BOOST_REQUIRE(r1.get()); BOOST_REQUIRE(r1a.get()); BOOST_REQUIRE_EQUAL(r1.get(), r1a.get()); + + BOOST_REQUIRE(r1a); + r1a.release(); + if (!r1a) { + BOOST_REQUIRE(true); + } + BOOST_REQUIRE(!r1a); + BOOST_REQUIRE_THROW(r1a.get(), std::runtime_error); + r1a = r2; + BOOST_REQUIRE(r1a); + BOOST_REQUIRE_EQUAL(r2.get(), r1a.get()); + if (r1a) { + BOOST_REQUIRE(true); + } } BOOST_REQUIRE_EQUAL(0, pool.inUseCount()); -- cgit v1.2.3