W dniu wtorek, 23 maja 2017 18:09:10 UTC+2 użytkownik Saúl Ibarra Corretgé 
napisał:
>
> On Tue, May 23, 2017 at 5:45 PM, Przemysław Sobala 
> <[email protected] <javascript:>> 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? 
>

another thread can call
uv_stop(loop);
uv_async_send(&loop_wakeup);
// wait for loop to successfully close
loop_mutex.lock();

then it blocks on loop_mutex.lock() and waits for uv_run to exit and 
release (unlock) the loop_mutex, after that it exists as well.

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