summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libadhocutil/resourcePool.h4
-rw-r--r--libadhocutil/resourcePool.impl.h35
-rw-r--r--libadhocutil/unittests/testResourcePool.cpp17
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());