Boost logo

Boost :

From: Richard Damon \(E-mail\) (RDamon_at_[hidden])
Date: 2002-03-25 21:07:23


I assume that the implementation of foo is what is starting the second
thread.

You seem to have a serious asymmetry in your specification. C code is
expected to manage the lifetime of the object, but you want C++ code to not
need to manage it. You are requiring the interface to be C based and not
allowed to know the type of caller. Your are asking foo to possibly manage a
resource that it does not know the source of. C code created it with malloc,
C++ code created it with new. You C++ example is violating the specs of the
Boost shared_ptr as the shared_ptr does not have total ownership of the
object. The definition of Boost's shared pointer does not allow for your
style of shared ownership.

I see your choices as the following:

1) Keep consistent ownership rules. Since the existing C interface has
caller ownership, the C++ needs the same. This means that if you are to use
shared_ptr you can not let it go out of scope until after you have confirmed
that foo is done. (This does not meet your requirement 4 which seems flawed)

2) You need a much smarter shared_ptr that can reconnect to other copies
from the stored pointer, and if there is none to remember that it does not
own it. A normal shared_ptr will not be smart enough to do this due to the
overhead that will be added, as it requires the keeping of a map of some
sort of values under controlled by all shared_ptrs in the program.

3) You need to eliminate condition 1. Since foo is starting another thread,
it is really just a wrapper to a client. It should not be a problem to have
two separate wrappers to model the two distinct object ownership rules. You
could have a

void the_real_foo(int*, shared_ptr<int>) {
... the original code, when you create a separate thread pass the shared_ptr
to it to keep the object alive
}

void foo(int* p){
        shared_ptr<int> sp; /* a dummy since C callers keep ownership */
        the_real_foo(p, sp);
}

void foo(shared_ptr<int> sp) {
        the_real_foo(sp.get(), sp);
}

4) You fire the designer who gave the impossible specs.

> -----Original Message-----
> From: boost-admin_at_[hidden]
> [mailto:boost-admin_at_[hidden]]On
> Behalf Of E. Gladyshev
> Sent: Monday, March 25, 2002 4:38 PM
> To: boost_at_[hidden]
> Subject: [boost] smart pointer puzzle
>
>
>
> I've decided to start another thread,
> since my original "plain pointers and shared_ptr"
> caused some confusion.
>
> To understand what I was talking about,
> here is a puzzle :).
>
> Objective:
> implement a smart pointer
> shared_pointer<int> and function foo( int* px )
> that does something on *px. foo() can
> use shared_pointer<int> but only internally.
>
> Requirements:
> 1. There must be only one version of foo() without
> any conditional compiling.
>
> 2. The foo() client and foo() can be running
> in different threads.
>
> 3. It should be obvious how to implement
> shared_pointer<int>
> in multi-thread environment.
>
> 4. foo() has to work correctly if the client uses
> shared_pointer<int> to share the 'px' object.
> In other words, if shared_pointer<int> goes out
> of scope on the client side while foo() is still
> using the object pointed by 'px' (can happen in
> multi-thread
> applications), the program should not crash.
> foo() has to call the object destructor when
> it exits and nobody else references the object.
>
> 5. foo() has to work consistently if the client
> is not using shared_pointer<int> ( a legacy
> C-code).
>
> 6. Following solutions are not accepted.
> - Solution 1. it is not possible.
> - Solution 2. change the foo() interface.
> - Solution 3. create multiple versions of foo().
>
>
> Here are some foo() usages:
>
> main()
> {
> {
> shared_pointer<int> x( new int );
> foo( x.get() );
> //make sure that foo() is started
> ...
> } //forget about 'x' here
>
> //do something else
> ...
>
> //make sure that foo() is done.
> ...
> return 0;
> }
>
> main()
> {
> int x;
> foo( &x );
> //wait when foo() is done.
> }
>
> main()
> {
> int *px = new x;
> foo( px );
>
> //wait when foo() is done.
> delete px;
> }
>
>
> See a proposed solution in my first
> "plain pointers and shared_ptr" message.
>
> Anybody has a better idea?
>


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