Boost logo

Boost :

From: Ben Hutchings (ben.hutchings_at_[hidden])
Date: 2004-09-27 08:24:37


John Torjo <john.lists_at_[hidden]> wrote:
> Alexander Terekhov wrote:
>
> > John Torjo wrote:
> > [...]
> >
> >>Whenever a thread (other than main) wants to access this window, it
> >>will query the weak_pointer. The weak_pointer needs to know the
> >>LATEST reference count in order to know if the weak pointer is still
> >>valid. Thus, atomic_read that simply returns the value is not
> >>enough.

However, the weak_ptr doesn't just use atomic_read. If atomic_read
returns 0 that means the use count has dropped to 0 [*] and can never
increase again, so it must be the latest version. Otherwise weak_ptr
makes a second test that is properly protected. So it can never use
an old value.

[*] I think this is right but I'm not certain that it can't return a
    0 that the processor read during creation of an object that
    uses enable_shared_from_this.

Having said all that, I feel the naming of functions may give a false
sense of generality and encapsulation when they actually only work in
the way they are being used currently.

<snip>
> Here's my scenario:
> (remember - we're talking about:
> http://www.pdimov.com/cpp/shared_count_x86_exp2.hpp)

This is still unaccessible. why don't you mail the code to Alexander
and me (or to the list, in case anyone else is interested)?

> class test { ... };
>
> [thread1]
> shared_ptr<test> p1( new test); // refcount = 1
>
> ---------------- thread switch

Switches between threads running on a single processor can't cause
problems here, because the use of "volatile" ensures that the
compiler won't reoder access to the use count and the processor will
only reorder memory access in a way that is invisible to the code
it's running. There might conceivably be problems that occur when
multiple threads run concurrently on multiple processors, in which
case reordering by one processor can affect another. So I'll ignore
the "thread switches".

> [thread2]
> shared_ptr<test> p2(p1); // refcount = 2
> weak_ptr<test> weak(p2);
> p2 = shared_ptr<test>(); // refcount = 1
>
> ------------------thread switch
> [thread1]
> p1 = shared_ptr<test>(); // refcount = 0 - object gets destroyed
> ---------------- thread switch
> [thread2]
>
> // here - you need InterlockedCompareExchange
> // to realize that refcount is 0 (zero)
> shared_ptr<test> p3 = weak.lock();

expired() may read the count as still being 1 and so return false,
but I believe the wnd_shared_ptr constructor will catch the fact
that the pointer really has expired. Unfortunately I can't yet
see the code to confirm this!

> Also, see my other post to Peter Dimov.

Seen it.

Ben.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk