Boost logo

Boost Users :

Subject: Re: [Boost-users] [boost][thread] Future returning 0xfeeefeee
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2013-04-07 16:48:30


Le 07/04/13 21:24, Klaim - Joël Lamotte a écrit :
>
> On Sun, Apr 7, 2013 at 8:05 PM, Vicente J. Botet Escriba
> <vicente.botet_at_[hidden] <mailto:vicente.botet_at_[hidden]>> wrote:
>
> Maybe, there is a difference between the interface std::vector you
> use in this example and your WorkQueue. Could you provide the
> prototype of the functions you are using of WorkQueue?
>
>
> Yes that's what I reported before: this code works until you use both
> boost::future/promise AND WorkQueue. I currently fixed production my
> code by just using std::future/promise.
> I've provided the full source code of WorkQueue in my first mail. I'll
> re-provide it here.
> It's a thin wrapper around a
> tbb::concurrent_queue<std::function<void()>> . (I'm using TBB 4.1 U2)
> Unfortunately the only clue that I can think about is that this
> container don't allow move-only value-type, so maybe it's linked to
> the problem
> but if not I have no idea.
> I also reported in the tbb forum see if they can spot something but
> the mix makes things hard to understand.
>
> Joel Lamotte
>
> ----
>
> class WorkQueue
> {
> public:
>
> template< class WorkTask >
> void push( WorkTask&& task )
> {
> m_task_queue.push( std::forward<WorkTask>( task ) );
> }
>
> /** Execute all the work queued until now. */
> void execute()
> {
> if( m_task_queue.empty() )
> return;
>
> bool end_of_work = false;
> m_task_queue.push( [&]{ end_of_work = true; } );
>
> std::function<void()> work;
> while( !end_of_work && m_task_queue.try_pop( work ) )
> {
> work();
> }
> }
>
> private:
>
> mutable tbb::concurrent_queue< std::function<void()> > m_task_queue;
> };
>
>
The main difference I see is the way the function is obtained:

When using vector the 'work' variable is a reference to the queue back,
there is no move no assignment of function<void()> objects.

       auto work = work_queue.back();
       work_queue.pop_back();

When using tbb the 'work' variable is default constructed and copied
using try_pop (see below).

std::function<void()> work;
while( !end_of_work && m_task_queue.try_pop( work ) )

I suspect that there could be an issue with the Boost.Thread
implementation here.

I don't master lambdas yet: does this the following code mean that
work_queue is taken by reference and promise by value on the pushed
lambda object?

   auto do_some_work = [&]()-> boost::future<int*>
   {
     auto promise = std::make_shared<boost::promise<int*>>();
     work_queue.push_back( [=]
     {
       promise->set_value( &TRUC );
     });

     return promise->get_future();

   };

----------------------
 From tbb documentation

bool try_pop ( T& destination )

If value is available, pops it from the queue, assigns it to
destination, and destroys the original value. Otherwise does nothing.

*Returns*: True if value was popped; false otherwise.



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net