1

So all my work happens inside of a class named thread_pool. This code will work no matter what run_item takes into itself:

template <class task_return_t>
    void thread_pool::pool_item( boost::shared_ptr< boost::packaged_task<task_return_t> > pt)
    {
        internal_tasks.post(boost::bind(&thread_pool::run_item<task_return_t>, this, pt));
//...

This will not compile:

template <class task_return_t>
    void thread_pool::pool_item( boost::shared_ptr< boost::packaged_task<task_return_t> > pt)
    {
         boost::packaged_task<void> task ( boost::bind(&thread_pool::run_item<task_return_t>, this, pt)));
        internal_tasks.post( task);

Why? And how to make it compile?

I use boost 1.47.0. Errors my VS2010 talls me:

Error   6   error C2665: 'boost::asio::detail::zero_arg_handler_test' : none of the 2 overloads could convert all the argument types    C:\Program Files (x86)\Boost-1.47.0\include\boost\asio\impl\io_service.hpp  88  1   cf-server

Error   9   error C2664: 'void boost::asio::detail::task_io_service::post<CompletionHandler>(Handler)' : cannot convert parameter 1 from 'const boost::packaged_task<R>' to 'boost::packaged_task<R>'   C:\Program Files (x86)\Boost-1.47.0\include\boost\asio\impl\io_service.hpp  90  1   cf-server

Error   8   error C2664: 'T &boost::asio::detail::lvref<CompletionHandler>(T)' : cannot convert parameter 1 from 'const boost::packaged_task<R>' to 'boost::packaged_task<R>'   C:\Program Files (x86)\Boost-1.47.0\include\boost\asio\impl\io_service.hpp  88  1   cf-server

Error   7   error C2664: 'boost::asio::detail::clvref' : cannot convert parameter 1 from 'const boost::packaged_task<R>' to 'boost::packaged_task<R>'   C:\Program Files (x86)\Boost-1.47.0\include\boost\asio\impl\io_service.hpp  88  1   cf-server
Rella
  • 65,003
  • 109
  • 363
  • 636

1 Answers1

2

It looks like the function thread_pool::run_item<task_return_t> accepts a non-const packaged task reference (or pointer) but boost::bind made a const copy, and is unable to pass the argument.

Without seeing the run_item signature, I can't tell exactly, but that's where I would look.

Edit: Looking a bit deeper (once I could get to a copy of boost 1_47), the problem is that boost::packaged_tasks are not copyable, however, boost::asio::io_service requires that CompletionHandler be CopyConstructable. Since boost::packaged_tasks are only MoveConstructable/MoveAssignable, you cannot pass them directly to the io_service.

See Boost.Asio requirements for CompletionHandlers

Dave S
  • 20,507
  • 3
  • 48
  • 68
  • 1
    yep - [fixed it in my threads_pool\task_manager](http://code.google.com/p/cloudobserver/source/browse/trunk/CloudServer/src/cf-util/thread_pool.h?spec=svn1478&r=1478) I create a bufer function that just executes task via `task()` – Rella Aug 31 '11 at 13:22