diff options
Diffstat (limited to 'cpp/lib/common/sys/AtomicCount.h')
-rw-r--r-- | cpp/lib/common/sys/AtomicCount.h | 58 |
1 files changed, 37 insertions, 21 deletions
diff --git a/cpp/lib/common/sys/AtomicCount.h b/cpp/lib/common/sys/AtomicCount.h index b625b2c9b0..7a9555480f 100644 --- a/cpp/lib/common/sys/AtomicCount.h +++ b/cpp/lib/common/sys/AtomicCount.h @@ -21,36 +21,52 @@ #include <boost/detail/atomic_count.hpp> #include <boost/noncopyable.hpp> +#include <boost/function.hpp> namespace qpid { namespace sys { /** - * Atomic counter. + * Increment counter in constructor and decrement in destructor. + * Optionally call a function if the decremented counter value is 0. + * Note the function must not throw, it is called in the destructor. */ -class AtomicCount : boost::noncopyable { +template <class Count> +class ScopedIncrement : boost::noncopyable { public: - class ScopedDecrement : boost::noncopyable { - public: - /** Decrement counter in constructor and increment in destructor. */ - ScopedDecrement(AtomicCount& c) : count(c) { value = --count; } - ~ScopedDecrement() { ++count; } - /** Return the value returned by the decrement. */ - operator long() { return value; } - private: - AtomicCount& count; - long value; - }; + ScopedIncrement(Count& c, boost::function0<void> f=0) + : count(c), callback(f) { ++count; } + ~ScopedIncrement() { if (--count == 0 && callback) callback(); } - class ScopedIncrement : boost::noncopyable { - public: - /** Increment counter in constructor and increment in destructor. */ - ScopedIncrement(AtomicCount& c) : count(c) { ++count; } - ~ScopedIncrement() { --count; } - private: - AtomicCount& count; - }; + private: + Count& count; + boost::function0<void> callback; +}; +/** Decrement counter in constructor and increment in destructor. */ +template <class Count> +class ScopedDecrement : boost::noncopyable { + public: + ScopedDecrement(Count& c) : count(c) { value = --count; } + ~ScopedDecrement() { ++count; } + + /** Return the value after the decrement. */ + operator long() { return value; } + + private: + Count& count; + long value; +}; + + +/** + * Atomic counter. + */ +class AtomicCount : boost::noncopyable { + public: + typedef ScopedIncrement<AtomicCount> ScopedIncrement; + typedef ScopedDecrement<AtomicCount> ScopedDecrement; + AtomicCount(long value = 0) : count(value) {} void operator++() { ++count ; } |