Boost logo

Boost Users :

From: Emil Wojak (emil_at_[hidden])
Date: 2007-08-19 14:01:16


Ovanes Markarian wrote:
>
> Ok, just looking at the example will bring more light into your questions.
>
> First non-safe scenario:
> // thread A
> p = p3; // reads p3, writes p
>
> // thread B
> p3.reset(); // writes p3; undefined, simultaneous read/write
>
>
> Either thread B is executed before thread A, then you assign empty shared
> pointer in thread A (to
> prior pointer deletion in thread B) OR thread A is executed before thread
> B, then a valid pointer
> is assigned in B. Possible scenario here as well: Value of p3 is read,
> scheduler switches to
> thread B; deletes pointer owned by p3; switches back to thread A and
> assignes invalid pointer
> value to p (deletion of pointee can happen probably twice and it is also
> undefined what is in
> memory at the point of assignment and what will be written later on...)
>
Hi, all!
I understand, that thread A could get an invalid pointer.
But what if thread B did not reset p3, but rather reassign it?
Assuming that I don't care if the reader gets the new pointee or the old
one.
I just wan't to assure that all dynamic objects would be deleted properly.

// pre-thread
boost::shared_ptr<const A> ptr(new A);

// reader thread A
boost::shared_ptr<const A> p1=ptr; // get the latest value
p1->getSomeValue();
p1->getSomeOtherValue();
p1.reset(); // don't need that anymore

// reader thread B
boost::shared_ptr<const A> p2=ptr; // get the latest value
p2->getSomeValue();
p2->getSomeOtherValue();
p2.reset(); // don't need that anymore

// writer thread
ptr.reset(new A); // look Ma! I've brought you something new!

So is the substitution thread-safe?
I think it could be, if the steps necessary to do that were taken in the
following order:
- setting new object's counter to 1 (atomicity irrelevant at this point)
- switching internal pointer to point to the new object (atomic) - from now
on, reader threads would get the new object
- decrementing old object's counter (atomic) - the old object gets released
and eventually deleted

If it's not that way, would this template class help in the abovementioned
use-scenario:

template <class T>
class SharedObject {
  public:
  typedef boost::shared_ptr<T> SharedPtr;
  SharedObject() : sharedPtr(new const SharedPtr(new T)) {}
  ~SharedObject() { delete sharedPtr; }
  SharedPtr get() { return *sharedPtr; }
  void set(T *httpLogFilter) {
    const SharedPtr *newSharedPtr=new SharedPtr(sharedObject);
    const SharedPtr *oldSharedPtr=sharedPtr;
    // there sould be a write membar here probably
    sharedPtr=newSharedPtr; // atomic substitution
    delete oldSharedPtr;
  }
  private:
  const SharedPtr *sharedPtr;
};

PS Would any valid compiler rearrange isntructions is set() ?

Thanks in advance for your help!

-- 
View this message in context: http://www.nabble.com/shared_ptr-and-thread-safety-tf4223939.html#a12224610
Sent from the Boost - Users mailing list archive at Nabble.com.

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net