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.
