From dbaf4f93615b0ad1f34b38ec9def0b30496658d7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 10 Mar 2007 12:11:21 +0000 Subject: - Bryan Henderson introduces two things: 1) the progress callback gets called more frequently (at times) 2) libcurl *might* call the callback when it receives a signal --- lib/transfer.c | 59 +++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 19 deletions(-) (limited to 'lib/transfer.c') diff --git a/lib/transfer.c b/lib/transfer.c index 8e6f5e19f..07e135ff1 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -1603,8 +1603,6 @@ CURLcode Curl_readwrite(struct connectdata *conn, failf(data, "transfer closed with outstanding read data remaining"); return CURLE_PARTIAL_FILE; } - if(Curl_pgrsUpdate(conn)) - return CURLE_ABORTED_BY_CALLBACK; } /* Now update the "done" boolean we return */ @@ -1754,6 +1752,18 @@ int Curl_single_getsock(struct connectdata *conn, } + +static bool +errnoIsInterruption(int errnoarg) +{ +#ifdef EINTR + return (errnoarg == EINTR); +#else + return FALSE; +#endif +} + + /* * Transfer() * @@ -1775,6 +1785,12 @@ Transfer(struct connectdata *conn) struct SessionHandle *data = conn->data; struct Curl_transfer_keeper *k = &data->reqdata.keep; bool done=FALSE; + sigset_t callersigmask; + sigset_t allsignals; + int pgrsrc; + int selectrc; + + sigfillset(&allsignals); if(!(conn->protocol & PROT_FILE)) { /* Only do this if we are not transferring FILE:, since the file: treatment @@ -1828,28 +1844,33 @@ Transfer(struct connectdata *conn) the timeout case and if we limit transfer speed we must make sure that this function doesn't transfer anything while in HOLD status. */ - switch (Curl_select(fd_read, fd_write, 1000)) { - case -1: /* select() error, stop reading */ -#ifdef EINTR - /* The EINTR is not serious, and it seems you might get this more - ofen when using the lib in a multi-threaded environment! */ - if(SOCKERRNO == EINTR) - ; - else -#endif - done = TRUE; /* no more read or write */ + sigprocmask(SIG_SETMASK, &allsignals, &callersigmask); + + pgrsrc = Curl_pgrsUpdate(conn); + + if(!pgrsrc) + selectrc = Curl_pselect(fd_read, fd_write, 3000, &callersigmask); + + sigprocmask(SIG_SETMASK, &callersigmask, NULL); + + if(pgrsrc) + return CURLE_ABORTED_BY_CALLBACK; + + if (selectrc == -1 && !errnoIsInterruption(SOCKERRNO)) { + done = TRUE; /* no more read or write */ continue; - case 0: /* timeout */ - default: /* readable descriptors */ + } else { + /* ready files, timeout, or signal received */ result = Curl_readwrite(conn, &done); - break; - } - if(result) - return result; - /* "done" signals to us if the transfer(s) are ready */ + /* "done" signals to us if the transfer(s) are ready */ + + if(result) + return result; + } } + Curl_pgrsUpdate(conn); return CURLE_OK; } -- cgit v1.2.3