Peter Dimov wrote:

> Pavel Vasiliev wrote:
>> May be the following code answers the challenge? :-).

> Interesting...

> [...]

>> void weak_ref_control_block::release_strong()
>> {
>>     if(atomic_decrement(&strong_count) == 0)
>>         strong_refs_lost();
>> }

>> bool weak_ref_control_block::acquire_strong_from_weak()
>> {
>>     scope_lock lock(mutex_destruct);
>>     if(atomic_increment(&strong_count) > 0)
>>         return true;
>>
>>     atomic_set(&strong_count, atomic_int_type_MIN);
>>     return false;
>> }

> Thread A, in release: atomic_decrement(&strong_count) == 0
> Thread B, in acquire: atomic_increment(&strong_count) > 0, return true
> Thread A: strong_refs_lost(); // oops, B hates us at this point

> Isn't this a problem? Not that I want to break it... I'd like a lock-less
> implementation, too. :-)

No! :-)

Thread A, in release_strong:
       atomic_decrement(&strong_count) == 0
Thread B, in acquire_strong_from_weak:
       lock,
       see atomic_increment(&strong_count) > 0,
       return true
Thread A:
       enter strong_refs_lost(),
       wait for lock,
       see strong_count == 1, do nothing.

Another scenario:
Thread A, in release_strong:
       atomic_decrement(&strong_count) == 0,
       enter strong_refs_lost(),
       lock
Thread B, in acquire_strong_from_weak:
       wait for lock
Thread A, in strong_refs_lost:
       see strong_count == 0,
       set strong_count < 0,
       unlock
       destroy,
Thread B, in acquire_strong_from_weak:
       see atomic_increment(&strong_count) < 0,
       restore negative strong_count,
       return false

       
Is that what you are asking?

Pavel

PS: still examining the Alexander's implementation...

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Reply via email to