Hello,

 

I wish to clarify a point on the thread-safety of shared_ptr. I have read the boost documentation on shared_ptr concerning Thread-Safety and amongst other things it gives this example (see  http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/shared_ptr.htm for the full set of examples):

 

   shared_ptr<int> p(new int(42));

 

   //--- Example 1 ---

 

   // thread A

   shared_ptr<int> p2(p); // reads p

 

   // thread B

   shared_ptr<int> p3(p); // OK, multiple reads are safe

 

   <snip...>

 

   //--- Example 4 ---

 

   // thread A

   p3 = p2; // reads p2, writes p3

 

   // thread B

   // p2 goes out of scope: undefined, the destructor is considered a "write access"

 

Given the nature of how the examples are presented, I have nonetheless presumed the examples are largely independent of one another, as opposed to each example being dependent on the results of the previous example. The specific question I have concerns the implications of the phrase "p2 goes out of scope".

 

I have a situation where I have a shared_ptr< Session > which is initially created by thread A. Many such objects in fact. A separate thread B cleans up periodically (the exact scenario is a .NET finaliser interfacing to native C++ code).

 

It is therefore entirely possible for the following two actions to happen simultaneously:

 

- Thread A is instantiating a new copy of shared_ptr< Session >, copied from an existing shared_ptr< Session >.

- Thread B is destroying a shared_ptr< Session >.

 

The above shared_ptrs are all referencing the same reference-counting object. I do not actually know which shared_ptr will be the one that actually destroys the underlying Session object (which is the whole point of me using shared_ptr as my cleanup ends up being non-deterministic with respect to sequence).

 

Example 4 is very important to me in terms of me understanding exactly what limitation they are describing. My possible interpretations are:

 

1. p2 goes out of scope under any circumstance. Doesn't matter if the shared_count is 1 or > 1 prior to the object going out of scope.

2. p2 goes out of scope, resulting in destruction of the underlying object.

 

In my interpretation of the example, when p2 goes out of scope, it will not result in destruction of the object, because p2 is a copy of p, and p is [presumably] still in scope. The outcome should merely be a decrementing of the reference count.

 

So I'm also at a bit of a loss to understand why an incrementing of a reference count is not considered a "write access" but a potential simple decrementing of a reference count (occurring via the shared_ptr destructor) is considered a "write access".

 

In my example I know I will never have thread A attempting to increment the ref count whilst thread B is potentially destroying the object simultaneously. When I get to my final copy of my object (ie. unique( ) is true), thread A is guaranteed to not be accessing or copying the shared_ptr when thread B commences the destruction of the final copy.

 

Will shared_ptr behave correctly or not in my situation?

 

Because if I take the boost example on simple face value, that I cannot have one shared_ptr going out of scope (and decrementing the ref count) whilst another thread is incrementing the ref count, then I'm feeling at a loss why boost would go to the trouble of a lock-free implementation in the first-place, since I would have thought my example is a pretty common (almost canonical) of why you would want thread-safety for shared_ptr. Now I'll be the first to admit that the boost guys are a lot smarter than me, so I'm hoping my understanding of the capability is simply wrong.

 

(The problem for me is that if shared_ptr does not provide the thread-safety requirements I need, then I must achieve that thread-safety external to shared_ptr with some kind of mutex, which puts me in a conundrum as to where such a mutex would be held. The obvious place would be my Session object since it provides the perfect granularity, but then I have the situation of having an object, which might potentially get deleted [when the last shared_ptr is destroyed], having a mutex referenced within it for the purpose of locking, which is clearly wrong.)

 

Any help will be greatly appreciated.

 

Thanks

 

Kevin