int event, int arg1, void *arg2)
{
CURLcode result = CURLE_OK;
- size_t i;
+ int i;
- for(i = 0; i < CURL_ARRAYSIZE(conn->cfilter); ++i) {
+ for(i = 0; i < (int)CURL_ARRAYSIZE(conn->cfilter); ++i) {
result = Curl_conn_cf_cntrl(conn->cfilter[i], data, ignore_result,
event, arg1, arg2);
if(!ignore_result && result)
* connect or shutdown does not add poll events for the other. Check
* against the transfer's own interest, before any chain added sockets
* of its own. */
- for(i = 0; (i < 2) && !result; ++i) {
+ for(i = 0; (i < (int)CURL_ARRAYSIZE(conn->cfilter)) && !result; ++i) {
if(conn->cfilter[i] &&
(want_io || !Curl_conn_is_connected(conn, i) ||
Curl_shutdown_started(conn, i)))
}
CURLcode Curl_conn_keep_alive(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex)
+ struct connectdata *conn)
{
- struct Curl_cfilter *cf;
+ CURLcode result = CURLE_OK;
+ int i;
- if(!CONN_SOCK_IDX_VALID(sockindex))
- return CURLE_BAD_FUNCTION_ARGUMENT;
- cf = conn->cfilter[sockindex];
- return cf ? cf->cft->keep_alive(cf, data) : CURLE_OK;
+ for(i = 0; (i < (int)CURL_ARRAYSIZE(conn->cfilter)) && !result; ++i) {
+ struct Curl_cfilter *cf = conn->cfilter[i];
+ if(cf)
+ result = cf->cft->keep_alive(cf, data);
+ }
+ return result;
}
size_t Curl_conn_get_max_concurrent(struct Curl_easy *data,
bool *input_pending);
/**
- * Try to upkeep the connection filters at sockindex.
+ * Try to upkeep the connection filters.
*/
CURLcode Curl_conn_keep_alive(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex);
+ struct connectdata *conn);
/**
* Get the remote hostname and port that the connection is currently
if(!terminate) {
reaper->checked++;
- terminate = Curl_conn_seems_dead(conn, data, &reaper->now);
+ terminate = Curl_cpool_conn_seems_dead(conn, data, &reaper->now);
}
if(terminate) {
/* stop the iteration here, pass back the connection that was pruned */
void *param)
{
(void)param;
- Curl_conn_upkeep(data, conn);
+ if(curlx_ptimediff_ms(Curl_pgrs_now(data), &conn->keepalive) >=
+ data->set.upkeep_interval_ms) {
+ CURLcode result;
+
+ /* briefly attach for action */
+ Curl_attach_connection(data, conn);
+ result = Curl_conn_keep_alive(data, conn);
+ conn->keepalive = *Curl_pgrs_now(data);
+ Curl_detach_connection(data);
+
+ if(result && !CONN_INUSE(conn)) {
+ Curl_conn_terminate(data, conn, FALSE);
+ return 1;
+ }
+ }
return 0; /* continue iteration */
}
return CURLE_OK;
CPOOL_LOCK(cpool, data);
- cpool_foreach(data, cpool, NULL, conn_upkeep);
+ while(cpool_foreach(data, cpool, NULL, conn_upkeep))
+ ;
CPOOL_UNLOCK(cpool, data);
return CURLE_OK;
}
}
}
+/* A connection has to have been idle for less than 'conn_max_idle_ms'
+ (the success rate is too low after this), or created less than
+ 'conn_max_age_ms' ago, to be subject for reuse. */
+static bool cpool_conn_maxage(struct Curl_easy *data,
+ struct connectdata *conn,
+ const struct curltime *pnow)
+{
+ timediff_t age_ms;
+
+ if(data->set.conn_max_idle_ms) {
+ age_ms = curlx_ptimediff_ms(pnow, &conn->lastused);
+ if(age_ms > data->set.conn_max_idle_ms) {
+ infof(data, "Too old connection (%" FMT_TIMEDIFF_T
+ " ms idle, max idle is %" FMT_TIMEDIFF_T " ms), disconnect it",
+ age_ms, data->set.conn_max_idle_ms);
+ return TRUE;
+ }
+ }
+
+ if(data->set.conn_max_age_ms) {
+ age_ms = curlx_ptimediff_ms(pnow, &conn->created);
+ if(age_ms > data->set.conn_max_age_ms) {
+ infof(data,
+ "Too old connection (created %" FMT_TIMEDIFF_T
+ " ms ago, max lifetime is %" FMT_TIMEDIFF_T " ms), disconnect it",
+ age_ms, data->set.conn_max_age_ms);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/*
+ * Return TRUE iff the given connection is considered dead.
+ */
+bool Curl_cpool_conn_seems_dead(struct connectdata *conn,
+ struct Curl_easy *data,
+ const struct curltime *pnow)
+{
+ bool input_pending = FALSE;
+ bool dead = FALSE;
+
+ DEBUGASSERT(!data->conn);
+ /* The check only makes sense only if the connection is not in use */
+ if(CONN_INUSE(conn))
+ return FALSE;
+ else if(cpool_conn_maxage(data, conn, pnow)) /* too old? */
+ return TRUE;
+ else if(curlx_ptimediff_ms(pnow, &conn->lastchecked) < 1000)
+ return FALSE;
+ else if(conn->scheme->run->connection_is_dead) {
+ Curl_attach_connection(data, conn);
+ dead = conn->scheme->run->connection_is_dead(data, conn);
+ Curl_detach_connection(data);
+ }
+ else {
+ Curl_attach_connection(data, conn);
+ dead = !Curl_conn_is_alive(data, conn, &input_pending);
+ Curl_detach_connection(data);
+ }
+
+ if(input_pending) {
+ /* For reuse, we want a "clean" connection state. This includes
+ * that we expect - in general - no waiting input data. Input
+ * waiting might be a TLS Notify Close, for example. We reject
+ * that.
+ * For protocols where data from other end may arrive at
+ * any time (HTTP/2 PING for example), the protocol handler needs
+ * to install its own `connection_check` callback.
+ */
+ DEBUGF(infof(data, "connection has input pending, not reusable"));
+ dead = TRUE;
+ }
+
+ return dead;
+}
+
#if 0
/* Useful for debugging the connection pool */
void Curl_cpool_print(struct cpool *cpool)
/* Close all unused connections, prevent reuse of existing ones. */
void Curl_cpool_nw_changed(struct Curl_easy *data);
+/**
+ * Return TRUE iff the given connection is considered dead.
+ */
+bool Curl_cpool_conn_seems_dead(struct connectdata *conn,
+ struct Curl_easy *data,
+ const struct curltime *pnow);
+
#endif /* HEADER_CURL_CONNCACHE_H */
}
#endif
-/* A connection has to have been idle for less than 'conn_max_idle_ms'
- (the success rate is too low after this), or created less than
- 'conn_max_age_ms' ago, to be subject for reuse. */
-static bool conn_maxage(struct Curl_easy *data,
- struct connectdata *conn,
- struct curltime now)
-{
- timediff_t age_ms;
-
- if(data->set.conn_max_idle_ms) {
- age_ms = curlx_ptimediff_ms(&now, &conn->lastused);
- if(age_ms > data->set.conn_max_idle_ms) {
- infof(data, "Too old connection (%" FMT_TIMEDIFF_T
- " ms idle, max idle is %" FMT_TIMEDIFF_T " ms), disconnect it",
- age_ms, data->set.conn_max_idle_ms);
- return TRUE;
- }
- }
-
- if(data->set.conn_max_age_ms) {
- age_ms = curlx_ptimediff_ms(&now, &conn->created);
- if(age_ms > data->set.conn_max_age_ms) {
- infof(data,
- "Too old connection (created %" FMT_TIMEDIFF_T
- " ms ago, max lifetime is %" FMT_TIMEDIFF_T " ms), disconnect it",
- age_ms, data->set.conn_max_age_ms);
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/*
- * Return TRUE iff the given connection is considered dead.
- */
-bool Curl_conn_seems_dead(struct connectdata *conn,
- struct Curl_easy *data,
- const struct curltime *pnow)
-{
- DEBUGASSERT(!data->conn);
- if(!CONN_INUSE(conn)) {
- /* The check for a dead socket makes sense only if the connection is not in
- use */
- bool dead;
-
- if(conn_maxage(data, conn, *pnow)) {
- /* avoid check if already too old */
- dead = TRUE;
- }
- else if(curlx_ptimediff_ms(pnow, &conn->lastchecked) < 1000)
- dead = FALSE;
- else if(conn->scheme->run->connection_is_dead) {
- /* The protocol has a special method for checking the state of the
- connection. Use it to check if the connection is dead. */
- /* briefly attach the connection for the check */
- Curl_attach_connection(data, conn);
- dead = conn->scheme->run->connection_is_dead(data, conn);
- Curl_detach_connection(data);
- conn->lastchecked = *pnow;
- }
- else {
- bool input_pending = FALSE;
-
- Curl_attach_connection(data, conn);
- dead = !Curl_conn_is_alive(data, conn, &input_pending);
- if(input_pending) {
- /* For reuse, we want a "clean" connection state. This includes
- * that we expect - in general - no waiting input data. Input
- * waiting might be a TLS Notify Close, for example. We reject
- * that.
- * For protocols where data from other end may arrive at
- * any time (HTTP/2 PING for example), the protocol handler needs
- * to install its own `connection_check` callback.
- */
- DEBUGF(infof(data, "connection has input pending, not reusable"));
- dead = TRUE;
- }
- Curl_detach_connection(data);
- conn->lastchecked = *pnow;
- }
-
- if(dead) {
- /* remove connection from cpool */
- infof(data, "Connection %" FMT_OFF_T " seems to be dead",
- conn->connection_id);
- return TRUE;
- }
- }
- return FALSE;
-}
-
-CURLcode Curl_conn_upkeep(struct Curl_easy *data,
- struct connectdata *conn)
-{
- CURLcode result = CURLE_OK;
- if(curlx_ptimediff_ms(Curl_pgrs_now(data), &conn->keepalive) <=
- data->set.upkeep_interval_ms)
- return result;
-
- /* briefly attach for action */
- Curl_attach_connection(data, conn);
- result = Curl_conn_keep_alive(data, conn, FIRSTSOCKET);
- Curl_detach_connection(data);
-
- conn->keepalive = *Curl_pgrs_now(data);
- return result;
-}
-
#ifdef USE_SSH
static bool ssh_config_matches(struct connectdata *one,
struct connectdata *two)
if(!url_match_multiplex_limits(conn, m))
return FALSE;
- if(!CONN_INUSE(conn) && Curl_conn_seems_dead(conn, m->data, &m->now)) {
+ if(Curl_cpool_conn_seems_dead(conn, m->data, &m->now)) {
/* remove and disconnect. */
+ infof(m->data, "Connection %" FMT_OFF_T " seems to be dead, terminating",
+ conn->connection_id);
Curl_conn_terminate(m->data, conn, FALSE);
return FALSE;
}
#define CURL_DEFAULT_HTTPS_PROXY_PORT 443 /* default https proxy port unless
specified */
-/**
- * Return TRUE iff the given connection is considered dead.
- */
-bool Curl_conn_seems_dead(struct connectdata *conn,
- struct Curl_easy *data,
- const struct curltime *pnow);
-
-/**
- * Perform upkeep operations on the connection.
- */
-CURLcode Curl_conn_upkeep(struct Curl_easy *data,
- struct connectdata *conn);
-
-/**
- * Always eval all arguments, return the first
- * result != (CURLE_OK | CURLE_AGAIN) or `r1`.
- */
+/* Always eval all arguments, return the first
+ * result != (CURLE_OK | CURLE_AGAIN) or `r1`. */
CURLcode Curl_1st_fatal(CURLcode r1, CURLcode r2);
#if defined(USE_HTTP2) || defined(USE_HTTP3)