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.
}
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;
}
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;
}
You can use RegisterWaitForSingleObject