In the code below, main() function is calling request() function which inter call th_request_async() function which mm_th_done_cb().
What will be the best and efficient way to proceed in main only after the mm_th_done_cb() is executed.
DUMMY CODE
int mm_th_done_cb(int error_code, th_result_s* th_result, void* user_data)
{
return 0;
}
void request()
{
th_request_s MyItemInfo;
strncpy(MyItemInfo.origin_path, szUrl, 1024+1);
MyItemInfo.orientation = 0;
MyItemInfo.func = mm_th_done_cb;
MyItemInfo.used_cache = 1;
th_request_async(MyItemInfo);
}
int main()
{
request();
// Here I need to do something only after mm_th_done_cb() has been excuted.
}
JavaScript provides a setTimeout() method which can work with the callback function and the await keyword to wait for a function to finish. The objective of employing these methods is to execute a piece of code after waiting for a specific time.
The keyword await is used to wait for a Promise. It can only be used inside an async function. This keyword makes JavaScript wait until that promise settles and returns its result.
The await keyword is used in an async function to ensure that all promises returned in the async function are synchronized, ie. they wait for each other. Await eliminates the use of callbacks in . then() and .
Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.
You can use std::promise
:
std::promise<int> promise;
int mm_th_done_cb(int error_code, th_result_s* th_result, void* user_data)
{
promise.set_value(error_code /*this value will be returned by the future.get()*/);
return 0;
}
int main()
{
std::future<int> future = promise.get_future();
request();
int value = future.get();
return 0;
}
If you don't need to return any value from the callback, then you can use a std::promise<void>
and std::future<void>
pair.
Both examples in wuqiang's answer are wrong.
1.
#include <future>
int main()
{
request();
// WRONG: Here we don't want to call 'mm_th_done_cb' ourselves.
std::future<int> myFuture = std::async(mm_th_done_cb);
//wait until mm_th_done_cb has been excuted;
int result = myFuture.get();
}
2.
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
int mm_th_done_cb(int error_code, th_result_s* th_result, void* user_data)
{
cv.notify_one();
return 0;
}
int main()
{
request();
// WRONG: If the 'request' finishes quickly, then the 'mm_th_done_cb'
// callback will be called and will notify the condition variable before
// the following lines execute, i.e. before the main thread starts
// waiting on the condition variable. Thus the 'cv.wait(lck)' will
// never return.
unique_lock<std::mutex> lck(mtx);
cv.wait(lck);
return 0;
}
If C++11 is available,you can std::future
#include <future>
int main()
{
request();
std::future<int> myFuture = std::async(mm_th_done_cb);
//wait until mm_th_done_cb has been excuted;
int result = myFuture.get();
}
or you can use synchronization mechanism.such as condition_variable,which is cross-platform.
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
int mm_th_done_cb(int error_code, th_result_s* th_result, void* user_data)
{
cv.notify_one();
return 0;
}
int main()
{
request();
unique_lock<std::mutex> lck(mtx);
cv.wait(lck);
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With