cURL / Mailing Lists / curl-library / Single Mail

curl-library

Interruptible curl_easy_perform()

From: Bryan Henderson <bryanh_at_giraffe-data.com>
Date: 25 Feb 2007 02:47:42 +0000

OK, I've got some code per the discussion so far. A patch is attached.

The patch is lengthy because there's some code movement. The actual
new lines of code is about 50. Here's what it does:

- progress callback can be called more than once a second.

- New function Curl_pselect() is like Curl_select() except that it
  has the pselect-style signal-unblock mask argument.

  Curl_select() now is just a loop around Curl_pselect. It feeds it a
  null signal mask and repeats it when it fails with EINTR.

  The Curl_select() in Transfer() is replaced with a Curl_pselect(),
  but the rest of the Curl_select()s are untouched.

- Curl_pselect() does what Curl_select() used to do, except it surrounds
  it with a signal unblock and restore. And to make the conditional
  compilation easier to read, it splits the original code into two functions:
  select_with_poll() and select_with_select().

- There's also a pselect-based receive_signals() that narrows the window
  of missed signals on a system that has pselect(). It momentarily
  unblocks signals and detects whether any waiting signal was received.
  Curl_pselect() calls that before doing anything else.

- select.c contains a treatise on the various means of waiting for I/O
  and how they respectively suck, and how libcurl deals with it.

- Transfer() blocks all signals and calls Curl_pselect() with an argument
  saying to unblock them during the wait. Calls to the progress function
  move slightly so one happens _before_ any waiting and they happen
  while signals are blocked to make sure signals don't get missed.

- Transfer() doesn't just retry on EINTR - it goes through the whole loop,
  including calling the progress callback.

-- 
Bryan Henderson                                   San Jose, California

Received on 2007-02-25