Boost logo

Boost :

From: William E. Kempf (williamkempf_at_[hidden])
Date: 2002-08-06 14:10:42


----- Original Message -----
From: "Fernando Cacciola" <fcacciola_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Tuesday, August 06, 2002 1:30 PM
Subject: Re: [boost] Re: Re: Threads & Exceptions

>
> ----- Original Message -----
> From: "George A. Heintzelman" <georgeh_at_[hidden]>
> To: <boost_at_[hidden]>
> Sent: Tuesday, August 06, 2002 2:04 PM
> Subject: Re: [boost] Re: Re: Threads & Exceptions
>
>
> >
> >
> > > I don't think so. There's no requirement for return values to be
> default
> > > constructable, but that's the only manner in which I can see to
> implement
> > > this. [ Return values from user functions in thread joins ]
> >
> > I think you can do it with a placement new, using only copy
> > constructors:
> >
> This is the exact mechanism used by the class optional<>, which is in the
> Files Section, under 'class optional', and which I am currently brushing
up.
> optional<> semantics are a bit different, but there is nevertheless some
> similarities and I'd like to consider this context as well.
>
> I've been only scanning through this discussion so didn't got all the
> details of your example: Could you post a more elaborate example, (with
some
> more context)?
> I want to see the similarities with optional<>.

The idea is to templatize boost::thread on the return type, thusly:

template <typename R>
class thread
{
public:
   thread(boost::function0<R> func);
   // other stuff
   R join();
};

Internally the implementation must map to something along the lines of
(pseudo code, not anything functional):

void proxy(void* p)
{
   data* d = static_cast<data*>(p);
   d->r = d->func();
}

thread::thread(function0<R> func)
// initialize m_d somehow
{
   create_native_thread(&proxy, &m_d);
}

R thread::join()
{
   native_join();
   return m_d.r;
}

The key is that the native proxy won't support return by value and must use
an in/out variable instead, but we want the result recorded there to be
returned during the call to join(), and we want the whole thing to work with
only the requirements imposed on return value types. This means the data::r
will be implemented with some aligned memory buffer and the proxy will use
placement new instead of assignment to "initialize" this buffer with the
return value that will later be used by join(). The tricky part of this is
the portable alignment implementation. This will mean that the value will
be copied twice, but I don't think that's all that important to know.

Bill Kempf


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