Subj : Re: A question about atomic_ptr To : comp.programming.threads From : Chris Thomasson Date : Sun Apr 17 2005 07:05 am > Chris Thomasson wrote: >> // *** shared_ptr *** >> >> >> 1. *Add this to public section: >> ----------------- >> >> void tricky_copy( shared_ptr &r ) >> { >> pn.tricky_copy( r.pn ); >> px = r.px; >> } > > But how do you avoid the usual problem of a thread being preempted after > pn.tricky_copy and before px = r.px? r.px may have been changed and no > longer in sync with the old r.pn. Yup, just noticed that. DWCAS would work. However, I am currently fiddling around with logic like this: // public shared_ptr function void tricky_copy_to_local( shared_ptr &src ) { // *this must be thread local if ( src.pn.pi_ ) { T *obj; detail::sp_counted_base *_base; ac_lfgc_smr_hazard_t hazard = ac_lfgc_smr_get( ac_thread_self(), 0 ); for ( ;; ) { obj = src.px; do { // setup hazard _base = (detail::sp_counted_base*) ac_lfgc_smr_activate ( hazard, (ac_cpu_node_t**)&src.pn.pi_ ); if ( ! _base ) { px = 0; if ( pn.pi_ ) { pn.pi_->release(); } pn.pi_ = 0; return; } // inc if > 0 } while ( ! _base->tricky_add_ref() ); // compare object after inc if ( obj == src.px ) { px = obj; if ( pn.pi_ ) { pn.pi_->release(); } pn.pi_ = _base; ac_lfgc_smr_deactivate( hazard ); break; } // retry _base->release(); } } else { px = src.px; pn = src.pn; } } I wonder if I am missing any race-conditions. The object compare after the increment should work... Humm... .