diff options
-rw-r--r-- | libadhocutil/resourcePool.h | 4 | ||||
-rw-r--r-- | libadhocutil/resourcePool.impl.h | 35 | ||||
-rw-r--r-- | 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 <typename R> ResourceHandle<R>::~ResourceHandle() { - decRef(); + if (resource) { + decRef(); + } } template <typename R> unsigned int ResourceHandle<R>::handleCount() const { + ASSERT(resource); return boost::get<2>(*resource); } @@ -41,20 +46,47 @@ namespace AdHoc { R * ResourceHandle<R>::get() const { + ASSERT(resource); return boost::get<0>(*resource); } template <typename R> + void + ResourceHandle<R>::release() + { + decRef(); + } + + template <typename R> + ResourceHandle<R>::operator bool() const + { + return resource; + } + + template <typename R> R * ResourceHandle<R>::operator->() const { + ASSERT(resource); return boost::get<0>(*resource); } template <typename R> void + ResourceHandle<R>::operator=(const ResourceHandle & rh) + { + if (resource) { + decRef(); + } + resource = rh.resource; + incRef(); + } + + template <typename R> + void ResourceHandle<R>::incRef() const { + ASSERT(resource); ++boost::get<2>(*resource); } @@ -62,6 +94,7 @@ namespace AdHoc { void ResourceHandle<R>::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()); |