libuv事件循环和libcurl

时间:2014-06-25 16:16:00

标签: c networking libuv

我在下面看到An example on how to use libuv with libcurl

的示例代码

主要功能如下所示:

int main(int argc, char **argv) {
    loop = uv_default_loop();

    if (argc <= 1)
        return 0;

    if (curl_global_init(CURL_GLOBAL_ALL)) {
        fprintf(stderr, "Could not init cURL\n");
        return 1;
    }

    uv_timer_init(loop, &timeout);

    curl_handle = curl_multi_init();
    curl_multi_setopt(curl_handle, CURLMOPT_SOCKETFUNCTION, handle_socket);
    curl_multi_setopt(curl_handle, CURLMOPT_TIMERFUNCTION, start_timeout);

    while (argc-- > 1) {
        add_download(argv[argc], argc);
    }

    uv_run(loop, UV_RUN_DEFAULT);
    curl_multi_cleanup(curl_handle);
    return 0;
}

我很困惑如何让事件循环开始。因为它看起来像我们执行这一行

uv_run(loop, UV_RUN_DEFAULT);

循环中根本没有待处理的事件,所以理论上不应该立即退出循环?

回调handle_socket应该没有运行的更改。 curl_perform()没有机会在curl套接字回调的回调中设置运行。

我的理解有什么问题吗?

3 个答案:

答案 0 :(得分:0)

来自uv_run的文档:

/*
* This function runs the event loop. It will act differently depending on the
* specified mode:
* - UV_RUN_DEFAULT: Runs the event loop until the reference count drops to
* zero. Always returns zero.
* - UV_RUN_ONCE: Poll for new events once. Note that this function blocks if
* there are no pending events. Returns zero when done (no active handles
* or requests left), or non-zero if more events are expected (meaning you
* should run the event loop again sometime in the future).
* - UV_RUN_NOWAIT: Poll for new events once but don't block if there are no
* pending events. Returns zero when done (no active handles
* or requests left), or non-zero if more events are expected (meaning you
* should run the event loop again sometime in the future).
*/

在您的情况下,您使用uv_run致电UV_RUN_DEFAULT,并且您的引用计数永远不会为零。这意味着循环将实际阻塞,直到您销毁其所有句柄和引用。但是,如果您使用UV_RUN_NOWAIT运行循环,函数将立即返回。

答案 1 :(得分:0)

uv_timer_init(loop, &timeout)未挂起套接字,因此它不会阻止uv循环,因为它不活动(您可以检查uv_handle_active) 但curl_multi_add_handle调用超时回调函数(start_timeout),此函数启动timeout计时器,uv_run调用on_timeout回调。 您可以在curl_multi_setopt(curl_handle, CURLMOPT_TIMERFUNCTION, start_timeout);循环后移动add_download进行测试,然后停止工作。

答案 2 :(得分:-1)

注册异步观察程序。使用uv_async_init永久强制循环。然后在异步回调中发布并处理所有新请求。