Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way for waiting for callback to finish

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.
}
like image 347
Vivek Kumar Avatar asked Dec 26 '14 04:12

Vivek Kumar


People also ask

How do you wait for callback function to finish?

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.

How do you wait for promise to finish?

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.

Can you await a callback?

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 .

How do you wait for async to finish?

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.


2 Answers

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;
}
like image 171
sinye Avatar answered Sep 19 '22 14:09

sinye


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;
}
like image 41
wuqiang Avatar answered Sep 23 '22 14:09

wuqiang