Unverified Commit 1b76c389 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

conn: remove the boolean 'inuse' field

... as the usage needs to be counted.
parent d6417f6c
Loading
Loading
Loading
Loading
+12 −18
Original line number Original line Diff line number Diff line
@@ -63,10 +63,9 @@


static void conn_llist_dtor(void *user, void *element)
static void conn_llist_dtor(void *user, void *element)
{
{
  struct connectdata *data = element;
  struct connectdata *conn = element;
  (void)user;
  (void)user;

  conn->bundle = NULL;
  data->bundle = NULL;
}
}


static CURLcode bundle_create(struct Curl_easy *data,
static CURLcode bundle_create(struct Curl_easy *data,
@@ -313,19 +312,20 @@ void Curl_conncache_remove_conn(struct connectdata *conn, bool lock)
     due to a failed connection attempt, before being added to a bundle */
     due to a failed connection attempt, before being added to a bundle */
  if(bundle) {
  if(bundle) {
    if(lock) {
    if(lock) {
      CONN_LOCK(conn->data);
      CONN_LOCK(data);
    }
    }
    conn->data = NULL; /* detach */
    bundle_remove_conn(bundle, conn);
    bundle_remove_conn(bundle, conn);
    if(bundle->num_connections == 0)
    if(bundle->num_connections == 0)
      conncache_remove_bundle(connc, bundle);
      conncache_remove_bundle(connc, bundle);
    conn->bundle = NULL; /* removed from it */
    conn->bundle = NULL; /* removed from it */
    if(connc) {
    if(connc) {
      connc->num_conn--;
      connc->num_conn--;
      DEBUGF(infof(conn->data, "The cache now contains %zu members\n",
      DEBUGF(infof(data, "The cache now contains %zu members\n",
                   connc->num_conn));
                   connc->num_conn));
    }
    }
    if(lock) {
    if(lock) {
      CONN_UNLOCK(conn->data);
      CONN_UNLOCK(data);
    }
    }
  }
  }
}
}
@@ -433,19 +433,11 @@ bool Curl_conncache_return_conn(struct connectdata *conn)
    infof(data, "Connection cache is full, closing the oldest one.\n");
    infof(data, "Connection cache is full, closing the oldest one.\n");


    conn_candidate = Curl_conncache_extract_oldest(data);
    conn_candidate = Curl_conncache_extract_oldest(data);

    if(conn_candidate) {
    if(conn_candidate) {
      /* Set the connection's owner correctly */
      conn_candidate->data = data;

      /* the winner gets the honour of being disconnected */
      /* the winner gets the honour of being disconnected */
      (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
      (void)Curl_disconnect(data, conn_candidate, /* dead_connection */ FALSE);
    }
    }
  }
  }
  CONN_LOCK(data);
  conn->inuse = FALSE; /* Mark the connection unused */
  conn->data = NULL; /* no owner */
  CONN_UNLOCK(data);


  return (conn_candidate == conn) ? FALSE : TRUE;
  return (conn_candidate == conn) ? FALSE : TRUE;


@@ -479,7 +471,7 @@ Curl_conncache_extract_bundle(struct Curl_easy *data,
  while(curr) {
  while(curr) {
    conn = curr->ptr;
    conn = curr->ptr;


    if(!conn->inuse) {
    if(!CONN_INUSE(conn)) {
      /* Set higher score for the age passed since the connection was used */
      /* Set higher score for the age passed since the connection was used */
      score = Curl_timediff(now, conn->now);
      score = Curl_timediff(now, conn->now);


@@ -496,6 +488,7 @@ Curl_conncache_extract_bundle(struct Curl_easy *data,
    data->state.conn_cache->num_conn--;
    data->state.conn_cache->num_conn--;
    DEBUGF(infof(data, "The cache now contains %zu members\n",
    DEBUGF(infof(data, "The cache now contains %zu members\n",
                 data->state.conn_cache->num_conn));
                 data->state.conn_cache->num_conn));
    conn_candidate->data = data; /* associate! */
  }
  }


  return conn_candidate;
  return conn_candidate;
@@ -536,7 +529,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
    while(curr) {
    while(curr) {
      conn = curr->ptr;
      conn = curr->ptr;


      if(!conn->inuse) {
      if(!CONN_INUSE(conn)) {
        /* Set higher score for the age passed since the connection was used */
        /* Set higher score for the age passed since the connection was used */
        score = Curl_timediff(now, conn->now);
        score = Curl_timediff(now, conn->now);


@@ -557,6 +550,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
    connc->num_conn--;
    connc->num_conn--;
    DEBUGF(infof(data, "The cache now contains %zu members\n",
    DEBUGF(infof(data, "The cache now contains %zu members\n",
                 connc->num_conn));
                 connc->num_conn));
    conn_candidate->data = data; /* associate! */
  }
  }
  CONN_UNLOCK(data);
  CONN_UNLOCK(data);


@@ -577,7 +571,7 @@ void Curl_conncache_close_all_connections(struct conncache *connc)
                                     pointer */
                                     pointer */
    /* This will remove the connection from the cache */
    /* This will remove the connection from the cache */
    connclose(conn, "kill all");
    connclose(conn, "kill all");
    (void)Curl_disconnect(conn, FALSE);
    (void)Curl_disconnect(connc->closure_handle, conn, FALSE);
    sigpipe_restore(&pipe_st);
    sigpipe_restore(&pipe_st);


    conn = Curl_conncache_find_first_connection(connc);
    conn = Curl_conncache_find_first_connection(connc);
+2 −2
Original line number Original line Diff line number Diff line
@@ -5,7 +5,7 @@
 *                            | (__| |_| |  _ <| |___
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *                             \___|\___/|_| \_\_____|
 *
 *
 * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 *
 * This software is licensed as described in the file COPYING, which
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * you should have received as part of this distribution. The terms
@@ -131,7 +131,7 @@ CURLcode Curl_async_resolved(struct connectdata *conn,
  if(result)
  if(result)
    /* We're not allowed to return failure with memory left allocated
    /* We're not allowed to return failure with memory left allocated
       in the connectdata struct, free those here */
       in the connectdata struct, free those here */
    Curl_disconnect(conn, FALSE); /* close the connection */
    Curl_disconnect(conn->data, conn, FALSE); /* close the connection */


  return result;
  return result;
}
}
+27 −21
Original line number Original line Diff line number Diff line
@@ -604,7 +604,7 @@ static CURLcode multi_done(struct connectdata **connp,
#endif
#endif
     ) || conn->bits.close
     ) || conn->bits.close
       || (premature && !(conn->handler->flags & PROTOPT_STREAM))) {
       || (premature && !(conn->handler->flags & PROTOPT_STREAM))) {
    CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */
    CURLcode res2 = Curl_disconnect(data, conn, premature);


    /* If we had an error already, make sure we return that one. But
    /* If we had an error already, make sure we return that one. But
       if we got a new error, return that. */
       if we got a new error, return that. */
@@ -622,7 +622,7 @@ static CURLcode multi_done(struct connectdata **connp,
             conn->bits.conn_to_host ? conn->conn_to_host.dispname :
             conn->bits.conn_to_host ? conn->conn_to_host.dispname :
             conn->host.dispname);
             conn->host.dispname);


    /* the connection is no longer in use */
    /* the connection is no longer in use by this transfer */
    if(Curl_conncache_return_conn(conn)) {
    if(Curl_conncache_return_conn(conn)) {
      /* remember the most recently used connection */
      /* remember the most recently used connection */
      data->state.lastconnect = conn;
      data->state.lastconnect = conn;
@@ -2109,7 +2109,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
            /* Don't attempt to send data over a connection that timed out */
            /* Don't attempt to send data over a connection that timed out */
            bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
            bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
            /* disconnect properly */
            /* disconnect properly */
            Curl_disconnect(data->easy_conn, dead_connection);
            Curl_disconnect(data, data->easy_conn, dead_connection);


            /* This is where we make sure that the easy_conn pointer is reset.
            /* This is where we make sure that the easy_conn pointer is reset.
               We don't have to do this in every case block above where a
               We don't have to do this in every case block above where a
@@ -2471,6 +2471,8 @@ void Curl_updatesocket(struct Curl_easy *data)


void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
{
{
  if(conn->data) {
    /* if there's still an easy handle associated with this connection */
    struct Curl_multi *multi = conn->data->multi;
    struct Curl_multi *multi = conn->data->multi;
    if(multi) {
    if(multi) {
      /* this is set if this connection is part of a handle that is added to
      /* this is set if this connection is part of a handle that is added to
@@ -2488,6 +2490,7 @@ void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
      }
      }
    }
    }
  }
  }
}


/*
/*
 * add_next_timeout()
 * add_next_timeout()
@@ -3135,12 +3138,15 @@ static void process_pending_handles(struct Curl_multi *multi)
  }
  }
}
}


void Curl_set_in_callback(struct Curl_easy *easy, bool value)
void Curl_set_in_callback(struct Curl_easy *data, bool value)
{
{
  if(easy->multi_easy)
  /* might get called when there is no data pointer! */
    easy->multi_easy->in_callback = value;
  if(data) {
  else if(easy->multi)
    if(data->multi_easy)
      easy->multi->in_callback = value;
      data->multi_easy->in_callback = value;
    else if(data->multi)
      data->multi->in_callback = value;
  }
}
}


bool Curl_is_in_callback(struct Curl_easy *easy)
bool Curl_is_in_callback(struct Curl_easy *easy)
+25 −31
Original line number Original line Diff line number Diff line
@@ -734,17 +734,20 @@ static void conn_free(struct connectdata *conn)
 * primary connection, like when freeing room in the connection cache or
 * primary connection, like when freeing room in the connection cache or
 * killing of a dead old connection.
 * killing of a dead old connection.
 *
 *
 * A connection needs an easy handle when closing down. We support this passed
 * in separately since the connection to get closed here is often already
 * disconnected from an easy handle.
 *
 * This function MUST NOT reset state in the Curl_easy struct if that
 * This function MUST NOT reset state in the Curl_easy struct if that
 * isn't strictly bound to the life-time of *this* particular connection.
 * isn't strictly bound to the life-time of *this* particular connection.
 *
 *
 */
 */


CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
CURLcode Curl_disconnect(struct Curl_easy *data,
                         struct connectdata *conn, bool dead_connection)
{
{
  struct Curl_easy *data;
  if(!conn)
  if(!conn)
    return CURLE_OK; /* this is closed and fine already */
    return CURLE_OK; /* this is closed and fine already */
  data = conn->data;


  if(!data) {
  if(!data) {
    DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n"));
    DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n"));
@@ -755,13 +758,13 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
   * If this connection isn't marked to force-close, leave it open if there
   * If this connection isn't marked to force-close, leave it open if there
   * are other users of it
   * are other users of it
   */
   */
  if(!conn->bits.close &&
  if(!conn->bits.close && CONN_INUSE(conn)) {
     (conn->send_pipe.size + conn->recv_pipe.size)) {
    DEBUGF(fprintf(stderr, "Curl_disconnect when inuse: %d\n",
    DEBUGF(infof(data, "Curl_disconnect, usecounter: %zu\n",
                   CONN_INUSE(conn)));
                 conn->send_pipe.size + conn->recv_pipe.size));
    return CURLE_OK;
    return CURLE_OK;
  }
  }


  conn->data = data;
  if(conn->dns_entry != NULL) {
  if(conn->dns_entry != NULL) {
    Curl_resolv_unlock(data, conn->dns_entry);
    Curl_resolv_unlock(data, conn->dns_entry);
    conn->dns_entry = NULL;
    conn->dns_entry = NULL;
@@ -959,7 +962,7 @@ static bool extract_if_dead(struct connectdata *conn,
                            struct Curl_easy *data)
                            struct Curl_easy *data)
{
{
  size_t pipeLen = conn->send_pipe.size + conn->recv_pipe.size;
  size_t pipeLen = conn->send_pipe.size + conn->recv_pipe.size;
  if(!pipeLen && !conn->inuse) {
  if(!pipeLen && !CONN_INUSE(conn)) {
    /* The check for a dead socket makes sense only if there are no
    /* The check for a dead socket makes sense only if there are no
       handles in pipeline and the connection isn't already marked in
       handles in pipeline and the connection isn't already marked in
       use */
       use */
@@ -1025,7 +1028,7 @@ static void prune_dead_connections(struct Curl_easy *data)
    while(Curl_conncache_foreach(data, data->state.conn_cache, &prune,
    while(Curl_conncache_foreach(data, data->state.conn_cache, &prune,
                                 call_extract_if_dead)) {
                                 call_extract_if_dead)) {
      /* disconnect it */
      /* disconnect it */
      (void)Curl_disconnect(prune.extracted, /* dead_connection */TRUE);
      (void)Curl_disconnect(data, prune.extracted, /* dead_connection */TRUE);
    }
    }
    data->state.conn_cache->last_cleanup = now;
    data->state.conn_cache->last_cleanup = now;
  }
  }
@@ -1139,7 +1142,7 @@ ConnectionExists(struct Curl_easy *data,


      if(extract_if_dead(check, data)) {
      if(extract_if_dead(check, data)) {
        /* disconnect it */
        /* disconnect it */
        (void)Curl_disconnect(check, /* dead_connection */TRUE);
        (void)Curl_disconnect(data, check, /* dead_connection */TRUE);
        continue;
        continue;
      }
      }


@@ -1267,12 +1270,12 @@ ConnectionExists(struct Curl_easy *data,
        }
        }
      }
      }


      if(!canpipe && check->inuse)
      if(!canpipe && CONN_INUSE(check))
        /* this request can't be pipelined but the checked connection is
        /* this request can't be pipelined but the checked connection is
           already in use so we skip it */
           already in use so we skip it */
        continue;
        continue;


      if((check->inuse) && (check->data->multi != needle->data->multi))
      if(CONN_INUSE(check) && (check->data->multi != needle->data->multi))
        /* this could be subject for pipeline/multiplex use, but only
        /* this could be subject for pipeline/multiplex use, but only
           if they belong to the same multi handle */
           if they belong to the same multi handle */
        continue;
        continue;
@@ -1464,7 +1467,6 @@ ConnectionExists(struct Curl_easy *data,


  if(chosen) {
  if(chosen) {
    /* mark it as used before releasing the lock */
    /* mark it as used before releasing the lock */
    chosen->inuse = TRUE;
    chosen->data = data; /* own it! */
    chosen->data = data; /* own it! */
    Curl_conncache_unlock(needle);
    Curl_conncache_unlock(needle);
    *usethis = chosen;
    *usethis = chosen;
@@ -4481,11 +4483,9 @@ static CURLcode create_conn(struct Curl_easy *data,
        conn_candidate = Curl_conncache_extract_bundle(data, bundle);
        conn_candidate = Curl_conncache_extract_bundle(data, bundle);
        Curl_conncache_unlock(conn);
        Curl_conncache_unlock(conn);


        if(conn_candidate) {
        if(conn_candidate)
          /* Set the connection's owner correctly, then kill it */
          (void)Curl_disconnect(data, conn_candidate,
          conn_candidate->data = data;
                                /* dead_connection */ FALSE);
          (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
        }
        else {
        else {
          infof(data, "No more connections allowed to host: %zu\n",
          infof(data, "No more connections allowed to host: %zu\n",
                max_host_connections);
                max_host_connections);
@@ -4504,12 +4504,9 @@ static CURLcode create_conn(struct Curl_easy *data,


      /* The cache is full. Let's see if we can kill a connection. */
      /* The cache is full. Let's see if we can kill a connection. */
      conn_candidate = Curl_conncache_extract_oldest(data);
      conn_candidate = Curl_conncache_extract_oldest(data);

      if(conn_candidate)
      if(conn_candidate) {
        (void)Curl_disconnect(data, conn_candidate,
        /* Set the connection's owner correctly, then kill it */
                              /* dead_connection */ FALSE);
        conn_candidate->data = data;
        (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
      }
      else {
      else {
        infof(data, "No connections available in cache\n");
        infof(data, "No connections available in cache\n");
        connections_available = FALSE;
        connections_available = FALSE;
@@ -4526,9 +4523,6 @@ static CURLcode create_conn(struct Curl_easy *data,
      goto out;
      goto out;
    }
    }
    else {
    else {
      /* Mark the connection as used, before we add it */
      conn->inuse = TRUE;

      /*
      /*
       * This is a brand new connection, so let's store it in the connection
       * This is a brand new connection, so let's store it in the connection
       * cache of ours!
       * cache of ours!
@@ -4693,9 +4687,9 @@ CURLcode Curl_connect(struct Curl_easy *data,
  }
  }


  if(result && *in_connect) {
  if(result && *in_connect) {
    /* We're not allowed to return failure with memory left allocated
    /* We're not allowed to return failure with memory left allocated in the
       in the connectdata struct, free those here */
       connectdata struct, free those here */
    Curl_disconnect(*in_connect, FALSE); /* close the connection */
    Curl_disconnect(data, *in_connect, FALSE);
    *in_connect = NULL; /* return a NULL */
    *in_connect = NULL; /* return a NULL */
  }
  }


+2 −1
Original line number Original line Diff line number Diff line
@@ -39,7 +39,8 @@ void Curl_freeset(struct Curl_easy * data);
CURLcode Curl_close(struct Curl_easy *data); /* opposite of curl_open() */
CURLcode Curl_close(struct Curl_easy *data); /* opposite of curl_open() */
CURLcode Curl_connect(struct Curl_easy *, struct connectdata **,
CURLcode Curl_connect(struct Curl_easy *, struct connectdata **,
                      bool *async, bool *protocol_connect);
                      bool *async, bool *protocol_connect);
CURLcode Curl_disconnect(struct connectdata *, bool dead_connection);
CURLcode Curl_disconnect(struct Curl_easy *data,
                         struct connectdata *, bool dead_connection);
CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);
CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);
CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done);
CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done);
Loading