|
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