On Tue, May 23, 2017 at 2:14 PM, Przemysław Sobala
<[email protected]> wrote:
> Hello
> I've modified a
> https://github.com/curl/curl/blob/master/docs/examples/multi-uv.c example to
> support adding new download requests via multiple threads.
>
> My design is this:
>
> 1) In main thread I setup and run uv_loop_t:
> loop_mutex.lock();
> uv_run(loop, UV_RUN_DEFAULT);
> loop_mutex.unlock();
> but to prevent this loop from quitting in the same thread I'm adding an
> async handle:
> uv_async_init(loop, &loop_wakup, NULL);
>
> 2) A thread can add a new downloading requrst by calling the Add method:
> void FileDownloader::Add(const string url, const string file_path,
> done_callback_t done_cb,
> error_callback_t error_cb) {
> curl_easy_ctx *easy_ctx = new curl_easy_ctx();
> easy_ctx->done_callback = done_cb;
> easy_ctx->error_callback = error_cb;
> easy_ctx->file = unique_ptr<File>(new File(file_path));
> CURL *handle = curl_easy_init();
> // downloaded data will be written to file
> curl_easy_setopt(handle, CURLOPT_WRITEDATA,
> easy_ctx->file->InternalHandle());
> // private single downloading context
> curl_easy_setopt(handle, CURLOPT_PRIVATE, easy_ctx);
> // fail if http response code is >= 400
> curl_easy_setopt(handle, CURLOPT_FAILONERROR, 1);
> // follow redirects
> curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1);
> // whole request timeout [sec]
> curl_easy_setopt(handle, CURLOPT_TIMEOUT, req_timeout);
> // URL to download
> curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
> // disable signal handlers
> curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1L);
> synchronized(curl_handle_mutex) {
> curl_multi_add_handle(curl_handle, handle);
> }
> uv_async_send(&loop_wakup);
> LOG(INFO) << "Downloading " << url << " -> " << file_path;
> }
> as you can see, after adding new curl easy handle I'm waking up the uv loop
> by calling uv_async_send
>
> Is this design correct?
>

I don't think so. With your design other threads will have to wait for
the loop to finish running (which will never happen if you have an
unref'd async handle) before they can call curl_multi_add_handle, thus
making the point of using multiple threads (if that's what you wanted
to do) moot.

What you can do instead is store the new curl handle in a QUEUE which
you protect with a mutex, and wakeup the loop. Then in the async
callback call curl_multi_add_handle for each curl handle in the queue.


Cheers,

-- 
/Saúl
bettercallsaghul.com

-- 
You received this message because you are subscribed to the Google Groups 
"libuv" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/libuv.
For more options, visit https://groups.google.com/d/optout.

Reply via email to