Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r54019 - trunk/boost/flyweight
From: joaquin_at_[hidden]
Date: 2009-06-17 14:58:07


Author: joaquin
Date: 2009-06-17 14:58:06 EDT (Wed, 17 Jun 2009)
New Revision: 54019
URL: http://svn.boost.org/trac/boost/changeset/54019

Log:
polished up [52457]
Text files modified:
   trunk/boost/flyweight/refcounted.hpp | 47 ++++++++++++++-------------------------
   1 files changed, 17 insertions(+), 30 deletions(-)

Modified: trunk/boost/flyweight/refcounted.hpp
==============================================================================
--- trunk/boost/flyweight/refcounted.hpp (original)
+++ trunk/boost/flyweight/refcounted.hpp 2009-06-17 14:58:06 EDT (Wed, 17 Jun 2009)
@@ -23,22 +23,20 @@
 #include <boost/utility/swap.hpp>
 
 /* Refcounting tracking policy.
- * The implementation deserves some explanation; values are equipped with a
- * reference count with the following semantics:
- * - 0: newly created value.
- * - n: (n-1) active references to the value.
- * When the number of references reaches zero, the value can be erased. The
- * exact protocol, however, is a little more complicated to avoid data races
- * like the following:
+ * The implementation deserves some explanation; values are equipped with two
+ * reference counts:
+ * - a regular count of active references
+ * - a deleter count
+ * It looks like a value can be erased when the number of references reaches
+ * zero, but this condition alone can lead to data races:
  * - Thread A detaches the last reference to x and is preempted.
  * - Thread B looks for x, finds it and attaches a reference to it.
  * - Thread A resumes and proceeds with erasing x, leaving a dangling
  * reference in thread B.
- * To cope with this, values are equipped with an additional count of threads
- * preempted during erasure. Such a preemption are detected by the preempting
- * thread by checking whether the reference count of the object is 1 (hence
- * the uncommon refcounting semantics distinguishing between a newly created
- * value and a value with no active references.
+ * Here is where the deleter count comes into play. This count is
+ * incremented when the reference count changes from 0 to 1, and decremented
+ * when a thread is about to check a value for erasure; it can be seen that a
+ * value is effectively erasable only when the deleter count goes down to 0.
  */
 
 namespace boost{
@@ -61,13 +59,13 @@
 
   ~refcounted_value()
   {
- /* count()>1 most likely indicates that the flyweight factory
+ /* count()!=0 most likely indicates that the flyweight factory
      * has been destructed before some of the flyweight objects using
      * it. Check for static initialization order problems with this
      * flyweight type.
      */
 
- BOOST_ASSERT(count()<=1);
+ BOOST_ASSERT(count()==0);
   }
 
   refcounted_value& operator=(const refcounted_value& r)
@@ -86,11 +84,10 @@
 
   long count()const{return ref;}
   long add_ref()const{return ++ref;}
- bool release()const{return (--ref==1);}
+ bool release()const{return (--ref==0);}
 
- long count_deleters()const{return del_ref;}
   void add_deleter()const{++del_ref;}
- void release_deleter()const{--del_ref;}
+ bool release_deleter()const{return (--del_ref==0);}
 
 private:
   Value x;
@@ -104,14 +101,8 @@
 public:
   explicit refcounted_handle(const Handle& h_):h(h_)
   {
- switch(TrackingHelper::entry(*this).add_ref()){
- case 1: /* newly created object, make count()==2 (1 active reference) */
- TrackingHelper::entry(*this).add_ref();
- break;
- case 2: /* object was about to be erased, increment the deleter count */
- TrackingHelper::entry(*this).add_deleter();
- break;
- default:break;
+ if(TrackingHelper::entry(*this).add_ref()==1){
+ TrackingHelper::entry(*this).add_deleter();
     }
   }
   
@@ -143,11 +134,7 @@
 private:
   static bool check_erase(const refcounted_handle& x)
   {
- if(TrackingHelper::entry(x).count_deleters()){
- TrackingHelper::entry(x).release_deleter();
- return false;
- }
- return true;
+ return TrackingHelper::entry(x).release_deleter();
   }
 
   Handle h;


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk