
Russell Hind wrote:
If you're referring to the ref-counted shared_ptr, then it has two counts it needs to keep track of, strong_count and weak_count, so InterlockedXXXXXX can't be used. Therefore the 'spin-lock' was introduced IIUC.
I like the looks of the 'shared_count_x86_exp2.hpp' code. I can't see how you could implement the 'atomic_conditional_increment' function with the atomic primitives supplied by gcc (atomicity.h) or the Linux kernel (atomic.h). The problem the weak pointers introduce is syncronization between the two counters (as Russell observed). I believe, however, that this is only an issue in 'add_ref_lock'. This is because we really have two interfaces here. A weak pointer interface and a strong pointer interface. A program that calls the strong interface from a weak pointer is in error (and would cause problems in the current implementation under the right conditons). Likewise for one that uses the weak interface from a strong pointer. Thus we can assume: 1) Code that calls a strong interface routine is telling us that both use_count_ and weak_count_ will not be concurrently decremented to zero by another thread (because our thread has at least one strong reference). 2) Code that calls a weak interface routine is telling us that the weak_count_ will not be concurrently decrement to zero by another thread (because our thread has at least one weak reference). If I am correct then, we could still do the following (as Windows, Linux, and gcc all provided atomic increment/decrement functions): // Strong interface void add_ref_copy(){ atomic_increment(use_count_); } void release(){ if(atomic_decrement(use_count_)) return; dispose(); weak_release(); } // Weak interface void add_ref_lock(){ mutex_type::scoped_lock lock(mtx_); if(atomic_increment(use_count_) == 1){ --use_count_; boost::throw_exception(boost::bad_weak_ptr()); } } void weak_add_ref(){ atomic_increment(weak_count_); } void weak_release(){ if(atomic_decrement(weak_count_)) return; destruct(); } -T NOTE: The gcc/Linux atomic operations return the prior value. The Windows operations return the new value. The above code uses the Windows style. -- Tyson Whitehead (-twhitehe@uwo.ca -- WSC-) Computer Engineer Dept. of Applied Mathematics, Graduate Student- Applied Mathematics University of Western Ontario, GnuPG Key ID# 0x8A2AB5D8 London, Ontario, Canada