summaryrefslogtreecommitdiffstats
path: root/Utilities/cmcurl/lib/multi.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmcurl/lib/multi.c')
-rw-r--r--Utilities/cmcurl/lib/multi.c152
1 files changed, 69 insertions, 83 deletions
diff --git a/Utilities/cmcurl/lib/multi.c b/Utilities/cmcurl/lib/multi.c
index 50bf15a..bb57dbc 100644
--- a/Utilities/cmcurl/lib/multi.c
+++ b/Utilities/cmcurl/lib/multi.c
@@ -459,7 +459,7 @@ struct Curl_multi *curl_multi_init(void)
CURL_DNS_HASH_SIZE);
}
-#ifdef DEBUGBUILD
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
static void multi_warn_debug(struct Curl_multi *multi, struct Curl_easy *data)
{
if(!multi->warned) {
@@ -638,7 +638,6 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
CONNCACHE_UNLOCK(data);
multi_warn_debug(multi, data);
- infof(data, "processing: %s", data->state.url);
return CURLM_OK;
}
@@ -668,8 +667,14 @@ static CURLcode multi_done(struct Curl_easy *data,
struct connectdata *conn = data->conn;
unsigned int i;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+ DEBUGF(infof(data, "multi_done[%s]: status: %d prem: %d done: %d",
+ multi_statename[data->mstate],
+ (int)status, (int)premature, data->state.done));
+#else
DEBUGF(infof(data, "multi_done: status: %d prem: %d done: %d",
(int)status, (int)premature, data->state.done));
+#endif
if(data->state.done)
/* Stop if multi_done() has already been called */
@@ -752,7 +757,7 @@ static CURLcode multi_done(struct Curl_easy *data,
if premature is TRUE, it means this connection was said to be DONE before
the entire request operation is complete and thus we can't know in what
- state it is for re-using, so we're forced to close it. In a perfect world
+ state it is for reusing, so we're forced to close it. In a perfect world
we can add code that keep track of if we really must close it here or not,
but currently we have no such detail knowledge.
*/
@@ -769,7 +774,7 @@ static CURLcode multi_done(struct Curl_easy *data,
#endif
) || conn->bits.close
|| (premature && !Curl_conn_is_multiplex(conn, FIRSTSOCKET))) {
- DEBUGF(infof(data, "multi_done, not re-using connection=%"
+ DEBUGF(infof(data, "multi_done, not reusing connection=%"
CURL_FORMAT_CURL_OFF_T ", forbid=%d"
", close=%d, premature=%d, conn_multiplex=%d",
conn->connection_id,
@@ -1105,8 +1110,7 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
if(multi->in_callback)
return CURLM_RECURSIVE_API_CALL;
- data = multi->easyp;
- while(data) {
+ for(data = multi->easyp; data; data = data->next) {
int bitmap;
#ifdef __clang_analyzer_
/* to prevent "The left operand of '>=' is a garbage value" warnings */
@@ -1115,30 +1119,21 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
bitmap = multi_getsock(data, sockbunch);
for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
- curl_socket_t s = CURL_SOCKET_BAD;
-
- if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK(sockbunch[i])) {
- if(!FDSET_SOCK(sockbunch[i]))
- /* pretend it doesn't exist */
- continue;
- FD_SET(sockbunch[i], read_fd_set);
- s = sockbunch[i];
- }
- if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK(sockbunch[i])) {
+ if((bitmap & GETSOCK_MASK_RW(i)) && VALID_SOCK((sockbunch[i]))) {
if(!FDSET_SOCK(sockbunch[i]))
/* pretend it doesn't exist */
continue;
- FD_SET(sockbunch[i], write_fd_set);
- s = sockbunch[i];
+ if(bitmap & GETSOCK_READSOCK(i))
+ FD_SET(sockbunch[i], read_fd_set);
+ if(bitmap & GETSOCK_WRITESOCK(i))
+ FD_SET(sockbunch[i], write_fd_set);
+ if((int)sockbunch[i] > this_max_fd)
+ this_max_fd = (int)sockbunch[i];
}
- if(s == CURL_SOCKET_BAD)
- /* this socket is unused, break out of loop */
+ else {
break;
- if((int)s > this_max_fd)
- this_max_fd = (int)s;
+ }
}
-
- data = data->next; /* check next handle */
}
*max_fd = this_max_fd;
@@ -1201,27 +1196,17 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
return CURLM_BAD_FUNCTION_ARGUMENT;
/* Count up how many fds we have from the multi handle */
- data = multi->easyp;
- while(data) {
+ for(data = multi->easyp; data; data = data->next) {
bitmap = multi_getsock(data, sockbunch);
- for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
- curl_socket_t s = CURL_SOCKET_BAD;
-
- if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) {
- ++nfds;
- s = sockbunch[i];
- }
- if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) {
+ for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) {
+ if((bitmap & GETSOCK_MASK_RW(i)) && VALID_SOCK((sockbunch[i]))) {
++nfds;
- s = sockbunch[i];
}
- if(s == CURL_SOCKET_BAD) {
+ else {
break;
}
}
-
- data = data->next; /* check next handle */
}
/* If the internally desired timeout is actually shorter than requested from
@@ -1261,49 +1246,42 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
if(curlfds) {
/* Add the curl handles to our pollfds first */
- data = multi->easyp;
- while(data) {
+ for(data = multi->easyp; data; data = data->next) {
bitmap = multi_getsock(data, sockbunch);
for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) {
- curl_socket_t s = CURL_SOCKET_BAD;
+ if((bitmap & GETSOCK_MASK_RW(i)) && VALID_SOCK((sockbunch[i]))) {
+ struct pollfd *ufd = &ufds[nfds++];
#ifdef USE_WINSOCK
- long mask = 0;
+ long mask = 0;
#endif
- if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) {
- s = sockbunch[i];
+ ufd->fd = sockbunch[i];
+ ufd->events = 0;
+ if(bitmap & GETSOCK_READSOCK(i)) {
#ifdef USE_WINSOCK
- mask |= FD_READ|FD_ACCEPT|FD_CLOSE;
+ mask |= FD_READ|FD_ACCEPT|FD_CLOSE;
#endif
- ufds[nfds].fd = s;
- ufds[nfds].events = POLLIN;
- ++nfds;
- }
- if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) {
- s = sockbunch[i];
+ ufd->events |= POLLIN;
+ }
+ if(bitmap & GETSOCK_WRITESOCK(i)) {
+#ifdef USE_WINSOCK
+ mask |= FD_WRITE|FD_CONNECT|FD_CLOSE;
+ reset_socket_fdwrite(sockbunch[i]);
+#endif
+ ufd->events |= POLLOUT;
+ }
#ifdef USE_WINSOCK
- mask |= FD_WRITE|FD_CONNECT|FD_CLOSE;
- reset_socket_fdwrite(s);
+ if(WSAEventSelect(sockbunch[i], multi->wsa_event, mask) != 0) {
+ if(ufds_malloc)
+ free(ufds);
+ return CURLM_INTERNAL_ERROR;
+ }
#endif
- ufds[nfds].fd = s;
- ufds[nfds].events = POLLOUT;
- ++nfds;
}
- /* s is only set if either being readable or writable is checked */
- if(s == CURL_SOCKET_BAD) {
- /* break on entry not checked for being readable or writable */
+ else {
break;
}
-#ifdef USE_WINSOCK
- if(WSAEventSelect(s, multi->wsa_event, mask) != 0) {
- if(ufds_malloc)
- free(ufds);
- return CURLM_INTERNAL_ERROR;
- }
-#endif
}
-
- data = data->next; /* check next handle */
}
}
@@ -1412,8 +1390,8 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
/* Count up all our own sockets that had activity,
and remove them from the event. */
if(curlfds) {
- data = multi->easyp;
- while(data) {
+
+ for(data = multi->easyp; data; data = data->next) {
bitmap = multi_getsock(data, sockbunch);
for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) {
@@ -1430,8 +1408,6 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
break;
}
}
-
- data = data->next;
}
}
@@ -1577,6 +1553,18 @@ static bool multi_ischanged(struct Curl_multi *multi, bool clear)
return retval;
}
+/*
+ * Curl_multi_connchanged() is called to tell that there is a connection in
+ * this multi handle that has changed state (multiplexing become possible, the
+ * number of allowed streams changed or similar), and a subsequent use of this
+ * multi handle should move CONNECT_PEND handles back to CONNECT to have them
+ * retry.
+ */
+void Curl_multi_connchanged(struct Curl_multi *multi)
+{
+ multi->recheckstate = TRUE;
+}
+
CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
struct Curl_easy *data,
struct connectdata *conn)
@@ -1611,7 +1599,6 @@ static CURLcode multi_do(struct Curl_easy *data, bool *done)
DEBUGASSERT(conn->handler);
if(conn->handler->do_it)
- /* generic protocol-specific function pointer set in curl_connect() */
result = conn->handler->do_it(data, done);
return result;
@@ -1787,9 +1774,8 @@ static CURLcode protocol_connect(struct Curl_easy *data,
*/
static CURLcode readrewind(struct Curl_easy *data)
{
- struct connectdata *conn = data->conn;
curl_mimepart *mimepart = &data->set.mimepost;
- DEBUGASSERT(conn);
+ DEBUGASSERT(data->conn);
data->state.rewindbeforesend = FALSE; /* we rewind now */
@@ -1802,12 +1788,12 @@ static CURLcode readrewind(struct Curl_easy *data)
/* We have sent away data. If not using CURLOPT_POSTFIELDS or
CURLOPT_HTTPPOST, call app to rewind
*/
- if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
- struct HTTP *http = data->req.p.http;
-
- if(http->sendit)
- mimepart = http->sendit;
+#ifndef CURL_DISABLE_HTTP
+ if(data->conn->handler->protocol & PROTO_FAMILY_HTTP) {
+ if(data->state.mimepost)
+ mimepart = data->state.mimepost;
}
+#endif
if(data->set.postfields ||
(data->state.httpreq == HTTPREQ_GET) ||
(data->state.httpreq == HTTPREQ_HEAD))
@@ -2460,7 +2446,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
if(done || (result == CURLE_RECV_ERROR)) {
/* If CURLE_RECV_ERROR happens early enough, we assume it was a race
- * condition and the server closed the re-used connection exactly when
+ * condition and the server closed the reused connection exactly when
* we wanted to use it, so figure out if that is indeed the case.
*/
CURLcode ret = Curl_retry_request(data, &newurl);
@@ -2502,7 +2488,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
if(result) {
/*
* The transfer phase returned error, we mark the connection to get
- * closed to prevent being re-used. This is because we can't possibly
+ * closed to prevent being reused. This is because we can't possibly
* know if the connection is in a good shape or not now. Unless it is
* a protocol which uses two "channels" like FTP, as then the error
* happened in the data connection.
@@ -2933,7 +2919,7 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
/* walk over the sockets we got right now */
for(i = 0; (i< MAX_SOCKSPEREASYHANDLE) &&
- (curraction & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i)));
+ (curraction & GETSOCK_MASK_RW(i));
i++) {
unsigned char action = CURL_POLL_NONE;
unsigned char prevaction = 0;