Reputation: 59
I want to implement a feature that will call the callback function once the promise will set the value of future.
I am using C++ boost 1.44 and I have tried below code, but it does not work as I expect to be, Can somebody correct the program.
void callback_function()
{
std::cout << "Final future is ready" << std::endl;
}
int main()
{
boost::promise<std::string> promise;
boost::unique_future<std::string> fut = promise.get_future();
promise.set_wait_callback(boost::bind(Callback_function));
promise.set_value("test");
sleep(10);
}
So there are two questions here,
How to call callback_function immediately after the promise.set_value("test") in the above program.
Also I tried to pass parameter to callback function as below, But this fail to compile saying no matching function to call to promise...
void callback_function( boost::unique_future<std::string> & fut)
{
std::cout << "Final future is ready with value" << fut.get() << std::endl;
}
int main()
{
boost::promise<std::string> promise;
boost::unique_future<std::string> fut = promise.get_future();
promise.set_wait_callback(boost::bind(Callback_function), boost::ref(fut));
promise.set_value("test");
sleep(10);
}
Added to the Question:
For the purpose of posting code, I have added sleep in my main function, But I actually want to continue lots of other code processing in the main thread. So that main thread will not block on fut.get or fut.wait automatic callback should happens once promise will set the value. I have seen once such implementation in http://braddock.com/~braddock/future/current/ but this implementation is not a part of boost thread where they have provided add_callback functionality to future. I am looking something similar in the official boost 1.44 thread and future implementation. It is going to be very nice feature to have. Once again one point I want to say that promise may be set in some other thread.
Thanks Abhishek
Upvotes: 2
Views: 3876
Reputation: 59
Here is the working code for me that I h ave come up, I came up with this approach because of limitations on boost 1.44 like it does not have boost::async and the thread lambda was also not compiling with my gcc compiler
boost version : 1.44 c++ compiler : gcc 4.3
#include <iostream>
#include "boost/thread.hpp"
#include "boost/thread/future.hpp"
#include "boost/bind.hpp"
void callback_test()
{
std::cout << "callback_test" << std::endl;
}
void promise_task(boost::promise<std::string> & promise)
{
std::cout << "promise_task" << std::endl;
// sleep (2);
promise.set_value("PROMISE");
}
void future_task(boost::unique_future<std::string> & future)
{
std::cout << "futute_task" << std::endl;
std::cout << future.get() << std::endl;
callback_test();
}
void promise_and_future_task(
boost::promise<std::string> & promise,
boost::unique_future<std::string> & future)
{
boost::thread promise_task_(&promise_task,
boost::ref(promise));
boost::thread future_task_(&future_task,
boost::ref(future));
}
void do_other_main_task()
{
sleep(5);
}
int main()
{
boost::promise<std::string> promise;
boost::unique_future<std::string> fut = promise.get_future();
// promise.set_wait_callback(boost::bind(callback_test));
boost::thread task(
&promise_and_future_task,
boost::ref(promise),
boost::ref(fut));
std::cout << "MAIN THREAD" << std::endl;
do_other_main_task();
return 0;
}
Upvotes: 1
Reputation: 393049
If you want to wait for the promise to be ready, just call wait()
(or one of the variants) on the future. That's what it's for.
The wait callback is there to notify the owner of the promise (or a "friend" :)) of the fact that somebody is waiting for the future:
#include <boost/thread/future.hpp>
void callback_function()
{
std::cout << "Wait is called and promise not ready yet" << std::endl;
}
int main()
{
boost::promise<std::string> promise;
boost::unique_future<std::string> fut = promise.get_future();
promise.set_wait_callback(boost::bind(callback_function));
boost::thread([&]{ sleep(2); promise.set_value("test"); });
sleep(1);
std::cout << fut.get();
}
This will print
Wait is called and promise not ready yet
test
(with 1 second before each line appearing). See it Live On Coliru)
To answer question 2:
Now, if you do the bind as you describe, accessing the future again will just result in an infinite recursion: See it Crash On Coliru
Update To answer question 1.
How to call callback_function immediately after the promise.set_value("test") in the above program
The simplest way would be:
promise.set_value("test");
callback_function();
Thought that might be too trivial. So, instead write:
boost::async([&]{ sleep(2); promise.set_value("test"); });
fut.wait(); // wait until promise is ready
callback_function(); // callback invocation
Upvotes: 1