
Peter Dimov wrote: [...]
Hm. You are right in theory, but in practice, I know that this is g++ on x86, and I know that it doesn't do such things.
(Aside: why invent naked_competing instead of just using nsync as per PL2?)
G++ is (relatively) easy to patch, and naked_competing simply sounds better. ;-) [...]
... you also have and manage client-provided "deleter" objects and I see no reason why weak_ptr clients may NOT have access to them (resulting in similar problem with respect to access and destruction as with Whitehead's mutex).
Hmmmm.
IIUC, you are saying that a thread can obtain access to the deleter using get_deleter, then hold on to the returned pointer after the shared_ptr is destroyed while holding only a weak_ptr to the object to keep the deleter alive?
Not necessarily just to keep the deleter alive. But ok, why not?
I'm having trouble picturing a situation where disallowing this will be a problem.
I'd rather provide template<class D, class T> D * get_deleter(weak_ptr<T> const & p); in addition to your existing template<class D, class T> D * get_deleter(shared_ptr<T> const & p);
Via the pointer you can only _read_ the deleter safely, and only if its operator() is const (because operator() can be called at any time.) Hence, you could have performed the reads beforehand, while still holding a shared_ptr.
Deleter can synchronize mutations (which might be caused by both shared_ptr and weak_ptr clients) internally with or *without* locks (using some lock-free stuff).
This aside, is this a problem on x86?
No.
I don't think it is since the load has acquire semantics either way.
Right. But I'd still (apart from evil-but-lawful G++ patches/new versions theory, not current practice) hide it in asm'd "may not store zero" decrement. regards, alexander.