Is weak_ptr lock method thread safe?

I googled this question but, although there are many discussions about it, I didn't find a clear answer. Can I assume the following piece of code to be thread safe? shared_ptr<T> p1(new XXX); //Main thread weak_ptr<T> wp(sp); //Main thread //Then I run two threads: A and B p1.reset(); //thread A shared_ptr<T> p2 = wp.lock(); // thread B In other words, is lock method atomic in respect to deference of the shared point? -- korg Firma *KORG ITALY SPA* *Via Cagiata, 85 -- 60027 Osimo (AN) - ITALY* *Ph. +39 071 727161 -Fax +39 071 7231228* *P.IVA e Cod. fiscale IT01460580424* *Soggetta al controllo della Società KORG Inc. - Giappone* *Reg. Imprese di n. 212056/1996 del 23/12/96* *REA di Ancona al n. 133105 del 06/12/96* *Capitale sociale Euro 814.253,16 i.v.* Ai sensi del D.Lgs. 30 giugno 2003, n. 196, "Codice in materia di protezione dei dati personali" si precisa che le informazioni contenute nel messaggio sono riservate e destinate esclusivamente alla persona od organizzazione sopra indicata. A chi legge il presente avviso - se non è l'effettivo destinatario, o un dipendente, o la persona responsabile della consegna del messaggio - si notifica che sono proibite copie, distribuzione o divulgazione di quanto in esso contenuto (C.P. 616). Se questo messaggio Vi è pervenuto per errore, Vi preghiamo di informarci immediatamente, di non leggerlo e di distruggerlo. Grazie. /According to Legislative Decree n. 196 of 30 June 2003 about "Personal Data Protection Code" we point out that the information contained in this message may be privileged and confidential and is intended only for the use of the individual entity named above. If the reader of this message is not the intended recipient, or an employee or agent responsible for delivering this message to the intended recipient, you are hereby notified that any dissemination, distribution, or copying of this message is strictly prohibited. If you have received this message in error, please notify us immediately and destroy the original message. //Thank you./

On Mon, Apr 22, 2013 at 10:26 AM, Andrea Galeazzi
In other words, is lock method atomic in respect to deference of the shared point?
Yes it is thread-safe, that's the whole point of the system: shared_ptr is implemented (in boost or std implementations) with an atomic counter used to sync the moment when the object need to be destroyed. Once the object is destroyed, all wp.lock() calls will return null shared_ptr. Just lock the shared_ptr from any thread (by copy) and check if it's null or not, or use wp.expired() if you don't want to aquire the object but just check if it's still alive. It is also good to know that there is some kind of synchronization on shared_ptr copy/construction that might in some cases, not be wanted for single-threaded applications where the cost isn't acceptable. Joel Lamotte

On Tue, 23 Apr 2013 18:25:40 +0200, Klaim - Joël Lamotte
On Mon, Apr 22, 2013 at 10:26 AM, Andrea Galeazzi
wrote: In other words, is lock method atomic in respect to deference of the shared point?
Yes it is thread-safe, that's the whole point of the system: shared_ptr is implemented (in boost or std implementations) with an atomic counter used to sync the moment when the object need to be destroyed.
Sure? Looking at boost 1.53 headers I see it is not thread safe: template<class T> class weak_ptr { ... shared_ptr<T> lock() const BOOST_NOEXCEPT { return shared_ptr<T>( *this, boost::detail::sp_nothrow_tag() ); } ... } template<class T> class shared_ptr { ... template<class Y> shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ) BOOST_NOEXCEPT : px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) { if( !pn.empty() ) { px = r.px; } } ... } -- Slava

Il 24/04/2013 8.56, Slava ha scritto:
On Tue, 23 Apr 2013 18:25:40 +0200, Klaim - Joël Lamotte
wrote: On Mon, Apr 22, 2013 at 10:26 AM, Andrea Galeazzi
wrote: In other words, is lock method atomic in respect to deference of the shared point?
Yes it is thread-safe, that's the whole point of the system: shared_ptr is implemented (in boost or std implementations) with an atomic counter used to sync the moment when the object need to be destroyed.
Sure? Looking at boost 1.53 headers I see it is not thread safe:
template<class T> class weak_ptr { ... shared_ptr<T> lock() const BOOST_NOEXCEPT { return shared_ptr<T>( *this, boost::detail::sp_nothrow_tag() ); } ... }
template<class T> class shared_ptr { ... template<class Y> shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ) BOOST_NOEXCEPT : px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) { if( !pn.empty() ) { px = r.px; } } ... }
-- Slava
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users So is it thread safe or not?

On Wed, Apr 24, 2013 at 4:49 PM, Andrea Galeazzi
So is it thread safe or not?
See : http://www.boost.org/doc/libs/1_53_0/libs/smart_ptr/shared_ptr.htm#ThreadSaf... "Starting with Boost release 1.33.0, shared_ptr uses a lock-free implementation on most common platforms. If your program is single-threaded and does not link to any libraries that might have used shared_ptr in its default configuration, you can #define the macro BOOST_SP_DISABLE_THREADS on a project-wide basis to switch to ordinary non-atomic reference count updates. (Defining BOOST_SP_DISABLE_THREADS in some, but not all, translation units is technically a violation of the One Definition Rule and undefined behavior. Nevertheless, the implementation attempts to do its best to accommodate the request to use non-atomic updates in those translation units. No guarantees, though.) You can define the macro BOOST_SP_USE_PTHREADS to turn off the lock-free platform-specific implementation and fall back to the generic pthread_mutex_t-based code." For std::thread, wikipedia state that: "Concurrency guarantees Multiple threads can safely access shared_ptr and weak_ptr objects that reference the same object simultaneously without the risk of a race condition. This is because all updates to the reference count is guaranteed to be doneatomically. Note that this only protects the reference count itself, and not the object being referenced by the smart pointer. The referenced object therefore needs to be protected separately to ensure thread safety." Globally, you should rely on the fact that boost/std::shared_ptr counting is atomic which suggests that it is ok to use weak_ptr in other threads. In practice, I have some code in heavily multithreaded context which rely on std::shared_ptr and std::weak_ptr (on VS2012) to be thread-safe and didn't have any problem so far (the code was in place for 8 months). Joel Lamotte

On Wed, Apr 24, 2013 at 8:56 AM, Slava
Sure? Looking at boost 1.53 headers I see it is not thread safe:
I believe the source isn't easy to follow on this, there are multiple macros depending on what platform and config macro you use. Also, I believe the atomic "lockfree" counting happen in the shared_count type, not directly into the shared_ptr class. Nevertheless, all documentation I found through years suggest that it is mandatory that shared_ptr counting is thread-safe because it makes sharing between threads dangerous otherwise. Unfortunately I don't have the standard available to check if std::shared_ptr is HAVE TO be implemented this way. Joel Lamotte

On Mon, Apr 22, 2013 at 4:26 AM, Andrea Galeazzi
I googled this question but, although there are many discussions about it, I didn't find a clear answer. Can I assume the following piece of code to be thread safe?
shared_ptr<T> p1(new XXX); //Main threadweak_ptr<T> wp(sp); //Main thread
//Then I run two threads: A and B p1.reset(); // thread A shared_ptr<T> p2 = wp.lock(); // thread B
In other words, is lock method atomic in respect to deference of the shared point?
Yes it is thread safe. To be clear (because I've seen this confusion before): shared_ptr<T> p1(new XXX); p1.reset(); // thread A p1.reset(); // thread B is NOT thread safe - used the same shared_ptr in 2 threads shared_ptr<T> p1(new XXX); shared_ptr<T> p2(p1); p1.reset(); // thread A p2.reset(); // thread B is thread safe - 2 shared_ptrs referencing the same object. Same with weak_ptr and various combinations. What you are doing is thread-safe. It is part of the docs, can be seen in the implementation (although it is hard to see), and tons of code would break if it wasn't. Tony

On Wed, 24 Apr 2013 18:30:13 +0200, Gottlob Frege
On Mon, Apr 22, 2013 at 4:26 AM, Andrea Galeazzi
wrote: I googled this question but, although there are many discussions about it, I didn't find a clear answer. Can I assume the following piece of code to be thread safe?
shared_ptr<T> p1(new XXX); //Main threadweak_ptr<T> wp(sp); //Main thread
//Then I run two threads: A and B p1.reset(); // thread A shared_ptr<T> p2 = wp.lock(); // thread B
In other words, is lock method atomic in respect to deference of the shared point?
< snip>
What you are doing is thread-safe. It is part of the docs, can be seen in the implementation (although it is hard to see), and tons of code would break if it wasn't.
Tony
Ok, after thorough debugging session today I backup the statement above. Your specific use-case is thread-safe, at least with boost 1.53 on x86 architecture. -- Slava
participants (5)
-
Andrea Galeazzi
-
Andrea Galeazzi
-
Gottlob Frege
-
Klaim - Joël Lamotte
-
Slava