aboutsummaryrefslogtreecommitdiff
path: root/lib/transfer.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2007-03-10 12:11:21 +0000
committerDaniel Stenberg <daniel@haxx.se>2007-03-10 12:11:21 +0000
commitdbaf4f93615b0ad1f34b38ec9def0b30496658d7 (patch)
treeb9299f0d71a7593ffc31201f5955d3f59076b6f1 /lib/transfer.c
parent433575068c60d107beb566259f061a66e529b581 (diff)
- 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
Diffstat (limited to 'lib/transfer.c')
-rw-r--r--lib/transfer.c59
1 files changed, 40 insertions, 19 deletions
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;
}