Wednesday 10 March 2021

curl_multi_wakeup doesn't seem to wakeup the associated curl_multi_poll - Android (but may not be limited to)

Curl version: 7.71.0 with c-ares

Background

We are building a library that's being integrated into mobile apps. We are targeting both iOS and Android. Curl initialisation happens in a static block inside the library.

The iOS version of the library is bundled into a framework, which is loaded at app startup, if i'm not mistaken. The Android version of the library is bundled in a module, which is lazily loaded. (I know this is an issue, especially since we link against OpenSSL, but it's probably important for context).

We built a small HTTP client with curl, that allows use to download some data blob from trusted servers.

Quick architecture review

The HTTP client is running on its own thread. It holds a curl_multi_handle, and any transfer started append a curl_easy_handle to it, and return a handle to a Response that contains a buffer to read the received bytes from, and is used to control the transfer if needed.

Since cURL handles are not thread safe, any action (referred to as Tasks from now on) to the handle is dispatched to the HTTP client's thread, and a boost::shared_future is returned (we might want to block or not depending on the use case).

Here is a rough idea of how the main loop is structured:

while (!done) {
    deal_with_transfer();
    check_transfer_status();
    cleanup_any_orphan_transfer();
    execute_all_queue_tasks();
    curl_multi_poll(multi, nullptr, 0, very_large_number, nullptr);
}

Appending to the task queue also performs a curl_multi_wakeup(multi) to make sure that task is executed (e.g. adding a new download is also a dispatched task).

The issue

We've only thus far tested on Android, and we've seen in some cases, HTTP client tasks that are blocking are sometimes never returning.

Logs and stacktraces show that we wait on a task being executed on by the HTTP client, but the client is still polling. Everything seems to indicate that it was't woken up when appending a task.

I can't seem to replicate the issue locally, on a device, but it happens often enough to be a blocker issue.

I'm a bit at a loss here, and I don't really know where to start looking to find a way to reproduce the issue, let alone fixing it.

I hope I gave enough context to start making educated guess, or even find a the source of error!

Thanks for reading!



from curl_multi_wakeup doesn't seem to wakeup the associated curl_multi_poll - Android (but may not be limited to)

No comments:

Post a Comment