curl / Mailing Lists / curl-library / Single Mail
Buy commercial curl support from WolfSSL. We help you work out your issues, debug your libcurl applications, use the API, port to new platforms, add new features and more. With a team lead by the curl founder himself.

Stoppable curl_easy_perform ?

From: Daniel Stenberg via curl-library <curl-library_at_cool.haxx.se>
Date: Mon, 7 Oct 2019 23:27:28 +0200 (CEST)

Hi all,

A frequent request and question over the years has been how you stop
curl_easy_perform() immediately from another thread.

The answer of course has always been that there's no built-in way to do that
but you have to make sure one of the callbacks return an error, which in the
worst case could be with a full second latency.

Now I'm here to propose a way we can improve the answer to that question and
I'm interested in feedback and comments on the API and the approach.

Consider curl_easy_stop(). Can be called from the same or another thread. This
stops the specific transfer *iff* that transfer was setup to *allow* being
externally stopped.

You enable a transfer to be stopped like this by using the share interface and
making sure that the share object the transfer uses has the new CURL_LOCK_STOP
bit set. That bit makes that transfer stoppable.

Psuedo code:

   CURLSH *share = curl_share_init();
   curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_STOP);
   curl_share_setopt(share, CURLSHOPT_LOCKFUNC, mutex_lock);
   ...

   CURL *easy = curl_easy_init();
   curl_easy_setopt(easy, CURLOPT_SHARE, share);

   curl_easy_perform(easy);

... now in another thread, this new API can be called:

   curl_easy_stop(easy);

Details:

When used from another thread, it is crucial that the CURLSHOPT_LOCKFUNC is
set so that we can lock the handle enough so that we can send a message on a
socketpair() over to the other thread and then unlock it again. (With PR #4466
we should soon have a decently portable socketpair situation to lean on.)

The thread performing a transfer will also wait for messages on a message pipe
that can be used to provide messages from the outside. Like for example an
instruction to stop.

I think a stopped transfer should return a return code saying it was stopped.
And if curl_easy_stop() is attempted on a transfer that hasn't been made
stoppable, a suitable error code should also be returned.

Good idea? Bad idea? Good enough API? Does the logic hold?

-- 
  / daniel.haxx.se | Get the best commercial curl support there is - from me
                   | Private help, bug fixes, support, ports, new features
                   | https://www.wolfssl.com/contact/
-------------------------------------------------------------------
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html
Received on 2019-10-07