Best way to wait for a callback

In the code below, the main () function calls the request () function, which calls the th_request_async () call function, which is mm_th_done_cb ().

What will be the best and most effective way to continue working only after executing mm_th_done_cb ().

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. } 
+6
source share
3 answers

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 a 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; } 
+4
source

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 do not need to return any value from the callback, you can use the std::promise<void> and std::future<void> pair.

Both examples in wuqiang's answer are incorrect.

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, ie 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; } 
+7
source
0
source

Source: https://habr.com/ru/post/980159/


All Articles