diff options
-rw-r--r-- | odb/shared-ptr/base.cxx | 14 | ||||
-rw-r--r-- | odb/shared-ptr/base.hxx | 11 | ||||
-rw-r--r-- | odb/shared-ptr/base.ixx | 9 |
3 files changed, 31 insertions, 3 deletions
diff --git a/odb/shared-ptr/base.cxx b/odb/shared-ptr/base.cxx index 56fc32c..197d20b 100644 --- a/odb/shared-ptr/base.cxx +++ b/odb/shared-ptr/base.cxx @@ -21,6 +21,20 @@ namespace odb { return "object is not shared"; } + + bool shared_base:: + _dec_ref_callback () + { + bool r (--counter_ == 0); + + if (r) + { + callback_->zero_counter (callback_->arg); + r = (counter_ == 0); + } + + return r; + } } // diff --git a/odb/shared-ptr/base.hxx b/odb/shared-ptr/base.hxx index 6fdc32e..4766aa7 100644 --- a/odb/shared-ptr/base.hxx +++ b/odb/shared-ptr/base.hxx @@ -68,8 +68,19 @@ namespace odb void operator delete (void*) throw (); + struct refcount_callback + { + void* arg; + void (*zero_counter) (void*); + }; + + private: + bool + _dec_ref_callback (); + protected: std::size_t counter_; + refcount_callback* callback_; }; template <typename X> diff --git a/odb/shared-ptr/base.ixx b/odb/shared-ptr/base.ixx index ee27fbe..61270a3 100644 --- a/odb/shared-ptr/base.ixx +++ b/odb/shared-ptr/base.ixx @@ -25,13 +25,13 @@ namespace odb inline shared_base:: shared_base () - : counter_ (1) + : counter_ (1), callback_ (0) { } inline shared_base:: shared_base (const shared_base&) - : counter_ (1) + : counter_ (1), callback_ (0) { } @@ -50,7 +50,10 @@ namespace odb inline bool shared_base:: _dec_ref () { - return --counter_ == 0; + if (callback_ == 0) + return --counter_ == 0; + else + return _dec_ref_callback (); } inline std::size_t shared_base:: |