aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2006-10-24 21:14:40 +0000
committerDaniel Stenberg <daniel@haxx.se>2006-10-24 21:14:40 +0000
commitf44ef427a2fbe506a35548ebab2b503438d6a027 (patch)
tree97213f027cf6ae257b4ced55e5a70e428ca146e9
parentc54a4301ee8ffec421ccfcb0a35f8261b109886f (diff)
other pipelining fixes by Ravi Pratap, that now makes pipelines get used better
-rw-r--r--lib/url.c95
1 files changed, 60 insertions, 35 deletions
diff --git a/lib/url.c b/lib/url.c
index 2cfbc9d4e..abbcafa04 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -158,6 +158,7 @@ static bool ConnectionExists(struct SessionHandle *data,
static long ConnectionStore(struct SessionHandle *data,
struct connectdata *conn);
static bool IsPipeliningPossible(struct SessionHandle *handle);
+static bool IsPipeliningEnabled(struct SessionHandle *handle);
static void conn_free(struct connectdata *conn);
static void signalPipeClose(struct curl_llist *pipe);
@@ -1790,8 +1791,10 @@ CURLcode Curl_disconnect(struct connectdata *conn)
Curl_ssl_close(conn);
/* Indicate to all handles on the pipe that we're dead */
- signalPipeClose(conn->send_pipe);
- signalPipeClose(conn->recv_pipe);
+ if (IsPipeliningEnabled(data)) {
+ signalPipeClose(conn->send_pipe);
+ signalPipeClose(conn->recv_pipe);
+ }
conn_free(conn);
@@ -1827,6 +1830,14 @@ static bool IsPipeliningPossible(struct SessionHandle *handle)
return FALSE;
}
+static bool IsPipeliningEnabled(struct SessionHandle *handle)
+{
+ if (handle->multi && Curl_multi_canPipeline(handle->multi))
+ return TRUE;
+
+ return FALSE;
+}
+
void Curl_addHandleToPipeline(struct SessionHandle *data,
struct curl_llist *pipe)
{
@@ -1937,21 +1948,44 @@ ConnectionExists(struct SessionHandle *data,
/* NULL pointer means not filled-in entry */
continue;
+ if (check->connectindex == -1) {
+ check->connectindex = i; /* Set this appropriately since it might have
+ been set to -1 when the easy was removed
+ from the multi */
+ }
+
+ infof(data, "Examining connection #%ld for reuse\n", check->connectindex);
+
+ if(check->inuse && !canPipeline) {
+ /* can only happen within multi handles, and means that another easy
+ handle is using this connection */
+ continue;
+ }
+
#ifdef CURLRES_ASYNCH
/* ip_addr_str is NULL only if the resolving of the name hasn't completed
yet and until then we don't re-use this connection */
- if (!check->ip_addr_str)
- continue;
-#endif
-
- if(check->inuse && !canPipeline)
- /* can only happen within multi handles, and means that another easy
- handle is using this connection */
+ if (!check->ip_addr_str) {
+ infof(data,
+ "Connection #%ld has not finished name resolve, can't reuse\n",
+ check->connectindex);
continue;
+ }
+#endif
if (check->send_pipe->size +
- check->recv_pipe->size >= MAX_PIPELINE_LENGTH)
+ check->recv_pipe->size >= MAX_PIPELINE_LENGTH) {
+ infof(data, "Connection #%ld has its pipeline full, can't reuse\n",
+ check->connectindex);
continue;
+ }
+
+ if (data->state.is_in_pipeline && check->bits.close) {
+ /* Don't pick a connection that is going to be closed */
+ infof(data, "Connection #%ld has been marked for close, can't reuse\n",
+ check->connectindex);
+ continue;
+ }
if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL))
/* don't do mixed SSL and non-SSL connections */
@@ -2002,33 +2036,22 @@ ConnectionExists(struct SessionHandle *data,
}
if(match) {
-
- bool dead = SocketIsDead(check->sock[FIRSTSOCKET]);
- if(dead) {
- if (!check->is_in_pipeline) {
+#if 1
+ if (!IsPipeliningEnabled(data)) {
+ /* The check for a dead socket makes sense only in the
+ non-pipelining case */
+ bool dead = SocketIsDead(check->sock[FIRSTSOCKET]);
+ if(dead) {
check->data = data;
- infof(data, "Connection %d seems to be dead!\n", i);
+ infof(data, "Connection #%d seems to be dead!\n", i);
Curl_disconnect(check); /* disconnect resources */
data->state.connc->connects[i]=NULL; /* nothing here */
- }
- else {
- /* In the pipelining case, freeing the connection right away
- * doesn't work. Instead, we mark the connection for close
- * so that the handles will detect this automatically when
- * they try to do something and deal with it there.
- * Prematurely freeing this connection prevents handles that
- * have already finished with their transfers to shut down
- * cleanly.
- */
- infof(data, "Connection %d seems dead - marking for close\n", i);
- check->bits.close = TRUE;
- }
- /* There's no need to continue searching, because we only store
- one connection for each unique set of identifiers */
- return FALSE;
+ return FALSE;
+ }
}
+#endif
check->inuse = TRUE; /* mark this as being in use so that no other
handle in a multi stack may nick it */
@@ -2045,10 +2068,12 @@ ConnectionExists(struct SessionHandle *data,
return TRUE; /* yes, we found one to use! */
}
}
+
return FALSE; /* no matching connecting exists */
}
+
/*
* This function frees/closes a connection in the connection cache. This
* should take the previously set policy into account when deciding which
@@ -2182,9 +2207,9 @@ static CURLcode ConnectPlease(struct SessionHandle *data,
Curl_addrinfo *addr;
char *hostname = data->change.proxy?conn->proxy.name:conn->host.name;
- infof(data, "About to connect() to %s%s port %d\n",
+ infof(data, "About to connect() to %s%s port %d (#%d)\n",
data->change.proxy?"proxy ":"",
- hostname, conn->port);
+ hostname, conn->port, conn->connectindex);
/*************************************************************
* Connect to server/proxy
@@ -2226,9 +2251,9 @@ static CURLcode ConnectPlease(struct SessionHandle *data,
*/
static void verboseconnect(struct connectdata *conn)
{
- infof(conn->data, "Connected to %s (%s) port %d\n",
+ infof(conn->data, "Connected to %s (%s) port %d (#%d)\n",
conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname,
- conn->ip_addr_str, conn->port);
+ conn->ip_addr_str, conn->port, conn->connectindex);
}
int Curl_protocol_getsock(struct connectdata *conn,