|
Boost : |
From: Pavel Vasiliev (pavel_at_[hidden])
Date: 2003-02-11 08:54:49
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...
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk