$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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.