Am Friday 04 September 2009 21:36:53 schrieb John Dlugosz:
can you point to anything that the boost shared_ptr does that is unsafe in the one-writer-multiple-reader case?
Just looking at the header, I see two direct members, px and pn. So straight assignment isn't going to copy the struct in one atomic operation.
Looking at operator=, I see two separate assignments.
I can see why it is not atomic in general. (although I still think the documentation should be changed. I don't think very many people understand that statement as "the c++ standard doesn't guarantee atomicity for builtin types, so shared_ptr isn't either", but as "I can do with shared_ptr anything I can do with an 'int' on my platform.) but I'm still not convinced that there's a lock required in my case, which was: "writing to an expired weak_ptr while multiple readers are trying to lock() it seems safe to me. (in the current implementation)" the relevant code is: writing: template<class Y> weak_ptr & operator=(shared_ptr<Y> const & r) // never throws { px = r.px; (*) pn = r.pn; return *this; } reading: template<class Y> explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw { // it is now safe to copy r.px, as pn(r.pn) did not throw px = r.px; } if we assume that the reads/writes are not reordered by the compiler (which I think is true because assigning to pn acquires a mutex or does something equivalent on lock-free platforms which should act as a memory barrier), then reading from a weak_ptr which was expired and is now in between assignment (at line marked with (*)) doesn't have any effect because the shared_ptr(weak_ptr) constructor only proceeds if there is a positive shared count. am I missing something?