Boost logo

Boost :

From: Rene Jager (renej_at_[hidden])
Date: 2001-08-22 14:52:31


Scott McCaskill wrote:

>>The attached emails show a problem with my "thread safe reference
>>count". If yours has the same problem, then the advice from
>>kaz_at_[hidden] (in the 2nd email) might be helpful to you.
>>In particular, if you ever do what I did in the main program in the
>>attachment, you'll have to increment the reference count from "outside
>>the smart pointer class" just before the pthread_create call to avoid
>>the problem, or, as Kaz points out, never pass the address of an auto
>>variable, even if its a "thread safe reference counted" SmartPtr.
>>
>
>I think we may be getting tripped up a bit on the terminology. In the code
>you sent, the problem is not so much with the reference _count_ but with the
>concurrent modifications to the smart _pointer_. The reference count is
>thread safe*--for example, if two threads simultaneously call inc_nrefs(),
>the accesses will be serialized correctly.
>
>OTOH, there is a problem (as was pointed out) with having two threads trying
>to modify the same smart pointer concurrently. So far I have always found
>it to be a good practice to think of smart pointers as being the same as POD
>types when it comes to concurrent modifications--just don't do it without
>external serialization.
>
>* -- there may be a potential problem in dec_nrefs() since it will result in
>unlocking an already destroyed mutex; I don't recall what behavior POSIX
>specifies for this (or if it's defined at all), but you may not have noticed
>any problems in that code since it doesn't check return values from the
>pthreads calls.
>
>The way I dealt with that problem was to unlock the mutex before doing the
>'delete this'. The problem, of course, is that that can introduce a race
>condition, but only _if_ anything else (possibly in another thread) has or
>could obtain a pointer to the object. This is why I became interested in
>making it impossible to ever have a raw pointer to the object. If I can
>guarantee that every pointer to the object is a smart pointer, then I know
>that when the reference count goes to 0, there really isn't anything else
>pointing to the object, and therefore no race condition is possible.
>Naturally this also depends on not sharing smart pointers between threads,
>but that's necessary anyway as discussed above.
>
>Attached is the intrusive solution I came up with. It's not thread safe,
>but that would be trivial to add. The code in main() shows explicitly what
>can and cannot be done with this idiom. The main thing I don't like about
>it is that classes derived from the base reference-counted object class need
>to have their constructors and destructor be private (or protected) and use
>factory methods for object creation in order to make it as difficult as
>possible to dynamically allocate an object without using a smart pointer,
>but there's no way to enforce this requirement using the language (that I've
>discovered).
>
I'm in a similar situation and ended up with something that makes object
creation
like this:

class Object
{
private:
    void * operator new (size_t);
    template <class T> friend class New;
};

class My_Type : virtual Object
{
public:
    My_Type (int i, double d);
};

extern Ref<Object> my_parent;
Ref<My_Type> x = New<My_Type>(my_parent, "a name")(3, 4.5);

the constructor args to the New<> are use to build a hierarchy of
objects (every object
is created and lives in the context of another object)
Ref<> is a strong pointer (also have weak pointer type Ptr)
with these three closely related pointer types; works pretty well for us;
maybe a strange syntax for object creation, but at least this helps to
make things safe
without relying on the programmers to remember the "don't forget" stuff.

The same is for thread-safety with respect to the objects themselves:
the pointers
lock the object on dereference and unlock when a temporary "deref-ptr"
is destructed
(normally at the end of the expression the operator -> or ->* is used)
I've seen to many times that programmers forgot to ensure mutual
exclusion that
this is what we ended up with (btw, works great and makes live a lot
easier; for the
application programmers that is)

renej

>
>
>
>Info: http://www.boost.org Unsubscribe: <mailto:boost-unsubscribe_at_[hidden]>
>
>Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>
> source.zip
>
> Content-Type:
>
> application/x-zip-compressed
> Content-Encoding:
>
> base64
>
>


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