No, this is not a valid DCLP implementation.
The fact is that your external check data.use_count() > 1 refers to an object (of type B with reference count ) that can be deleted (without links) in the part protected by the mutex. Any memory traps there cannot help.
Why data.use_count () accesses an object:
Assume that these operations are completed:
shared_ptr<B> data1 = make_shared<B>(...); shared_ptr<B> data = data1;
Then you have the following layout ( weak_ptr support is not shown here):
data1 [allocated with B::new()] data
Each shared_ptr object is simply a pointer that points to the allocated memory area. This memory area includes an object of type B plus an atomic counter reflecting the number shared_ptr pointing to this object. When this counter goes to zero, the memory area is freed (and object B destroyed). It is this counter that is returned by shared_ptr::use_count() .
UPDATE : execution, which can lead to access to already freed memory (initially two points shared_ptr for the same object, .use_count() is 2):
Enter detach() Enter detach() Found `data.use_count()` > 1 Enter critical section Found `data.use_count()` > 1 Dereference `data`, found old object. Unreference old `data`, `use_count` becomes 1 Delete other shared_ptr, old object is deleted Assign new object to `data` Access old object (for check `use_count`) !! But object is freed !!
An external check should only accept a pointer to an object to decide whether to block access.
By the way, even your implementation will be correct, it has little meaning:
If data (and detach ) can be accessed from several streams at the same time, the uniqueness of an object does not give any advantages, since it can be accessed from several streams. If you want to change the object, all calls to data must be protected by an external mutex, in this case detach() cannot be executed at the same time.
If data (and detach ) can only be accessed by one thread at a time, the detach implementation does not need to be blocked at all.
source share