On Tue, May 23, 2017 at 5:45 PM, Przemysław Sobala
<[email protected]> wrote:
> W dniu wtorek, 23 maja 2017 16:48:46 UTC+2 użytkownik Saúl Ibarra Corretgé
> napisał:
>>
>> 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,
>
>
> Hi Saul
>
> I've though of that. My flow is as follows:
> 1) initialization of uv_loop_t and curl_multi handle
> 2) running mentioned uv_loop_t in separate thread - endlessly by adding an
> async handle
> 3) "client" threads are calling Add method (it's body is in the first post)
>
> It seems to do it's job, do you have any comments on that?
>

I don't see how :-) Given the loop thread takes the lock before
calling uv_run, and uv_run runs endlessly, when will it let go fo the
lock?

-- 
/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