#include #include #include #include template class future : private boost::noncopyable { public: typedef ResultType result_type; template future(Demuxer& d, Function f) { d.post(future_call(*this, f)); } result_type operator()() { event_.wait(); return result_; } template class future_call { public: future_call(future& fut, Function func) : future_(fut), function_(func) { } void operator()() { future_.result_ = function_(); future_.event_.signal(); } private: future& future_; Function function_; }; // These ought to be private, but public for now to work around lack of // templates as friends on some compilers. //private: result_type result_; asio::detail::event event_; }; int square(int value) { // Block the thread to simulate some work. asio::demuxer tmp_demuxer; asio::timer timer(tmp_demuxer, asio::time::now() + 5); timer.wait(); return value * value; } int main() { // Run future in main loop. try { asio::demuxer d; future f(d, boost::bind(square, 5)); d.run(); std::cout << f() << std::endl; } catch (asio::error&) { } // Run future in separate thread. try { asio::demuxer d; d.work_started(); // To keep run() alive even when no other work to do. asio::thread th(boost::bind(&asio::demuxer::run, &d)); future f(d, boost::bind(square, 4)); std::cout << f() << std::endl; d.work_finished(); // To allow the run() function to end. th.join(); } catch (asio::error&) { } // Run future in thread pool. try { asio::demuxer d; d.work_started(); // To keep run() alive even when no other work to do. asio::thread th1(boost::bind(&asio::demuxer::run, &d)); asio::thread th2(boost::bind(&asio::demuxer::run, &d)); future f1(d, boost::bind(square, 3)); future f2(d, boost::bind(square, 7)); std::cout << f1() << std::endl; std::cout << f2() << std::endl; d.work_finished(); // To allow the run() function to end. th1.join(); th2.join(); } catch (asio::error&) { } return 0; }