Boost logo

Boost :

From: Alexander Terekhov (terekhov_at_[hidden])
Date: 2003-02-10 14:12:59


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.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk