Pavel Vasiliev wrote:
> 
> Alexander Terekhov wrote:
> 
> [...]
> >> Pavel Vasiliev wrote:
> >> > The true locking/unlocking, not InterlockedIncrement/Decrement()
> >                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 
> > Nah, pthread_refcount_t. ;-)
> 
> >> > even if availabe, is necessary to support weak references.
> >> > [...]
> >>
> 
> > It's probably a bit more exciting to take care of all possible races
> > without "a true lock" protecting both counters. I'm not sure that the
> > true locking is *necessary* to support weak references. Do you have
> > an illustration, Pavel?
> 
> May be the following code answers the challenge? :-). ...

Not bad. ;-) Well,

//*** ES and error checking aside...

class refs { 
public:

  refs() {
    pthread_refcount_init(&strong_count, 1);
    pthread_refcount_init(&weak_count, 1); 
  }

 ~refs() {
    pthread_refcount_destroy(&weak_count);
    pthread_refcount_destroy(&strong_count);
  }

  //*** Called by existing "strong_ptr".

  void acquire_strong() {
    pthread_refcount_increment(&strong_count);
  }

  void release_strong() {
    int status = pthread_refcount_decrement(&strong_count);
    if (PTHREAD_REFCOUNT_DROPPED_TO_ZERO == status) {
      destruct_object();
      release_weak();
    }
  }

  void acquire_weak_from_strong() {
    acquire_weak();
  }

  //*** Called by existing "weak_ref".

  void acquire_weak() {
    pthread_refcount_increment( &weak_count );
  }

  void release_weak() {
    int status = pthread_refcount_decrement_no_msync(&weak_count);
    if (PTHREAD_REFCOUNT_DROPPED_TO_ZERO == status) 
      destruct_self();
  }

  bool acquire_strong_from_weak() {
    int status = pthread_refcount_enroll_one(&strong_count); // _many( &refcount, 1);
    if (PTHREAD_REFCOUNT_DROPPED_TO_ZERO == status) // Ouch, did not work [too late].
      return false;
    return true;
  }

private:

  void destruct_object(); // "delete p_object".
  void destruct_self();   // "delete this".

  pthread_refcount_t strong_count;  
  pthread_refcount_t weak_count;    

  T* p_object;

}; //*** class refs

Or am I just missing and/or misunderstanding something?

regards,
alexander.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Reply via email to