mirror of
https://github.com/curl/curl.git
synced 2026-08-25 07:43:32 +03:00
lib: add meta_hash to connection, eliminate hash_offt
With a meta_hash at each connection (similar to easy handle, let multi_ev.c store its pollsets as meta data, no longer needing its own hashes. This eliminates the last use of Curl_hash_offt. Remove it. Closes #17095
This commit is contained in:
parent
1d66a769d7
commit
657aae79c0
18 changed files with 126 additions and 343 deletions
|
|
@ -27,6 +27,7 @@
|
|||
#include <curl/curl.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "url.h"
|
||||
#include "cfilters.h"
|
||||
#include "curl_trc.h"
|
||||
#include "multiif.h"
|
||||
|
|
@ -57,7 +58,7 @@ static void mev_in_callback(struct Curl_multi *multi, bool value)
|
|||
*/
|
||||
struct mev_sh_entry {
|
||||
struct uint_spbset xfers; /* bitset of transfers `mid`s on this socket */
|
||||
struct Curl_hash_offt conns; /* hash of connections using this socket */
|
||||
struct connectdata *conn; /* connection using this socket or NULL */
|
||||
void *user_data; /* libcurl app data via curl_multi_assign() */
|
||||
unsigned int action; /* CURL_POLL_IN/CURL_POLL_OUT we last told the
|
||||
* libcurl application to watch out for */
|
||||
|
|
@ -84,7 +85,6 @@ static void mev_sh_entry_dtor(void *freethis)
|
|||
{
|
||||
struct mev_sh_entry *entry = (struct mev_sh_entry *)freethis;
|
||||
Curl_uint_spbset_destroy(&entry->xfers);
|
||||
Curl_hash_offt_destroy(&entry->conns);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +117,6 @@ mev_sh_entry_add(struct Curl_hash *sh, curl_socket_t s)
|
|||
return NULL; /* major failure */
|
||||
|
||||
Curl_uint_spbset_init(&check->xfers);
|
||||
Curl_hash_offt_init(&check->conns, CURL_MEV_CONN_HASH_SIZE, NULL);
|
||||
|
||||
/* make/add new hash entry */
|
||||
if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
|
||||
|
|
@ -136,7 +135,7 @@ static void mev_sh_entry_kill(struct Curl_multi *multi, curl_socket_t s)
|
|||
|
||||
static size_t mev_sh_entry_user_count(struct mev_sh_entry *e)
|
||||
{
|
||||
return Curl_uint_spbset_count(&e->xfers) + Curl_hash_offt_count(&e->conns);
|
||||
return Curl_uint_spbset_count(&e->xfers) + (e->conn ? 1 : 0);
|
||||
}
|
||||
|
||||
static bool mev_sh_entry_xfer_known(struct mev_sh_entry *e,
|
||||
|
|
@ -148,7 +147,7 @@ static bool mev_sh_entry_xfer_known(struct mev_sh_entry *e,
|
|||
static bool mev_sh_entry_conn_known(struct mev_sh_entry *e,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
return !!Curl_hash_offt_get(&e->conns, conn->connection_id);
|
||||
return (e->conn == conn);
|
||||
}
|
||||
|
||||
static bool mev_sh_entry_xfer_add(struct mev_sh_entry *e,
|
||||
|
|
@ -164,7 +163,11 @@ static bool mev_sh_entry_conn_add(struct mev_sh_entry *e,
|
|||
{
|
||||
/* detect weird values */
|
||||
DEBUGASSERT(mev_sh_entry_user_count(e) < 100000);
|
||||
return !!Curl_hash_offt_set(&e->conns, conn->connection_id, conn);
|
||||
DEBUGASSERT(!e->conn);
|
||||
if(e->conn)
|
||||
return FALSE;
|
||||
e->conn = conn;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -180,7 +183,12 @@ static bool mev_sh_entry_xfer_remove(struct mev_sh_entry *e,
|
|||
static bool mev_sh_entry_conn_remove(struct mev_sh_entry *e,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
return Curl_hash_offt_remove(&e->conns, conn->connection_id);
|
||||
DEBUGASSERT(e->conn == conn);
|
||||
if(e->conn == conn) {
|
||||
e->conn = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Purge any information about socket `s`.
|
||||
|
|
@ -344,11 +352,11 @@ static CURLMcode mev_pollset_diff(struct Curl_multi *multi,
|
|||
return CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
CURL_TRC_M(data, "ev entry fd=%" FMT_SOCKET_T ", added %s #%" FMT_OFF_T
|
||||
", total=%u/%zu (xfer/conn)", s,
|
||||
", total=%u/%d (xfer/conn)", s,
|
||||
conn ? "connection" : "transfer",
|
||||
conn ? conn->connection_id : data->mid,
|
||||
Curl_uint_spbset_count(&entry->xfers),
|
||||
Curl_hash_offt_count(&entry->conns));
|
||||
entry->conn ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
for(j = 0; j < prev_ps->num; j++) {
|
||||
|
|
@ -414,9 +422,9 @@ static CURLMcode mev_pollset_diff(struct Curl_multi *multi,
|
|||
if(mresult)
|
||||
return mresult;
|
||||
CURL_TRC_M(data, "ev entry fd=%" FMT_SOCKET_T ", removed transfer, "
|
||||
"total=%u/%zu (xfer/conn)", s,
|
||||
"total=%u/%d (xfer/conn)", s,
|
||||
Curl_uint_spbset_count(&entry->xfers),
|
||||
Curl_hash_offt_count(&entry->conns));
|
||||
entry->conn ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
mresult = mev_forget_socket(multi, data, s, "last user gone");
|
||||
|
|
@ -430,15 +438,22 @@ static CURLMcode mev_pollset_diff(struct Curl_multi *multi,
|
|||
return CURLM_OK;
|
||||
}
|
||||
|
||||
static void mev_pollset_dtor(void *key, size_t klen, void *entry)
|
||||
{
|
||||
(void)key;
|
||||
(void)klen;
|
||||
free(entry);
|
||||
}
|
||||
|
||||
static struct easy_pollset*
|
||||
mev_add_new_conn_pollset(struct Curl_hash_offt *h, curl_off_t id)
|
||||
mev_add_new_conn_pollset(struct connectdata *conn)
|
||||
{
|
||||
struct easy_pollset *ps;
|
||||
|
||||
ps = calloc(1, sizeof(*ps));
|
||||
if(!ps)
|
||||
return NULL;
|
||||
if(!Curl_hash_offt_set(h, id, ps)) {
|
||||
if(Curl_conn_meta_set(conn, CURL_META_MEV_POLLSET, ps, mev_pollset_dtor)) {
|
||||
free(ps);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -446,14 +461,14 @@ mev_add_new_conn_pollset(struct Curl_hash_offt *h, curl_off_t id)
|
|||
}
|
||||
|
||||
static struct easy_pollset*
|
||||
mev_add_new_xfer_pollset(struct uint_hash *h, unsigned int id)
|
||||
mev_add_new_xfer_pollset(struct Curl_easy *data)
|
||||
{
|
||||
struct easy_pollset *ps;
|
||||
|
||||
ps = calloc(1, sizeof(*ps));
|
||||
if(!ps)
|
||||
return NULL;
|
||||
if(!Curl_uint_hash_set(h, id, ps)) {
|
||||
if(Curl_meta_set(data, CURL_META_MEV_POLLSET, ps, mev_pollset_dtor)) {
|
||||
free(ps);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -461,16 +476,14 @@ mev_add_new_xfer_pollset(struct uint_hash *h, unsigned int id)
|
|||
}
|
||||
|
||||
static struct easy_pollset *
|
||||
mev_get_last_pollset(struct Curl_multi *multi,
|
||||
struct Curl_easy *data,
|
||||
mev_get_last_pollset(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
if(data) {
|
||||
if(conn)
|
||||
return Curl_hash_offt_get(&multi->ev.conn_pollsets,
|
||||
conn->connection_id);
|
||||
return Curl_conn_meta_get(conn, CURL_META_MEV_POLLSET);
|
||||
else if(data)
|
||||
return Curl_uint_hash_get(&multi->ev.xfer_pollsets, data->mid);
|
||||
return Curl_meta_get(data, CURL_META_MEV_POLLSET);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -494,15 +507,13 @@ static CURLMcode mev_assess(struct Curl_multi *multi,
|
|||
struct easy_pollset ps, *last_ps;
|
||||
|
||||
mev_init_cur_pollset(&ps, data, conn);
|
||||
last_ps = mev_get_last_pollset(multi, data, conn);
|
||||
last_ps = mev_get_last_pollset(data, conn);
|
||||
|
||||
if(!last_ps && ps.num) {
|
||||
if(conn)
|
||||
last_ps = mev_add_new_conn_pollset(&multi->ev.conn_pollsets,
|
||||
conn->connection_id);
|
||||
last_ps = mev_add_new_conn_pollset(conn);
|
||||
else
|
||||
last_ps = mev_add_new_xfer_pollset(&multi->ev.xfer_pollsets,
|
||||
data->mid);
|
||||
last_ps = mev_add_new_xfer_pollset(data);
|
||||
if(!last_ps)
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
@ -588,7 +599,7 @@ void Curl_multi_ev_expire_xfers(struct Curl_multi *multi,
|
|||
while(Curl_uint_spbset_next(&entry->xfers, mid, &mid));
|
||||
}
|
||||
|
||||
if(Curl_hash_offt_count(&entry->conns))
|
||||
if(entry->conn)
|
||||
*run_cpool = TRUE;
|
||||
}
|
||||
}
|
||||
|
|
@ -605,7 +616,7 @@ void Curl_multi_ev_xfer_done(struct Curl_multi *multi,
|
|||
DEBUGASSERT(!data->conn); /* transfer should have been detached */
|
||||
if(data != multi->admin) {
|
||||
(void)mev_assess(multi, data, NULL);
|
||||
Curl_uint_hash_remove(&multi->ev.xfer_pollsets, data->mid);
|
||||
Curl_meta_remove(data, CURL_META_MEV_POLLSET);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -614,36 +625,18 @@ void Curl_multi_ev_conn_done(struct Curl_multi *multi,
|
|||
struct connectdata *conn)
|
||||
{
|
||||
(void)mev_assess(multi, data, conn);
|
||||
Curl_hash_offt_remove(&multi->ev.conn_pollsets, conn->connection_id);
|
||||
Curl_conn_meta_remove(conn, CURL_META_MEV_POLLSET);
|
||||
}
|
||||
|
||||
#define CURL_MEV_PS_HASH_SLOTS (991) /* nice prime */
|
||||
|
||||
static void mev_hash_conn_pollset_free(curl_off_t id, void *entry)
|
||||
{
|
||||
(void)id;
|
||||
free(entry);
|
||||
}
|
||||
|
||||
static void mev_hash_xfer_pollset_free(unsigned int id, void *entry)
|
||||
{
|
||||
(void)id;
|
||||
free(entry);
|
||||
}
|
||||
|
||||
void Curl_multi_ev_init(struct Curl_multi *multi, size_t hashsize)
|
||||
{
|
||||
Curl_hash_init(&multi->ev.sh_entries, hashsize, mev_sh_entry_hash,
|
||||
mev_sh_entry_compare, mev_sh_entry_dtor);
|
||||
Curl_uint_hash_init(&multi->ev.xfer_pollsets,
|
||||
CURL_MEV_PS_HASH_SLOTS, mev_hash_xfer_pollset_free);
|
||||
Curl_hash_offt_init(&multi->ev.conn_pollsets,
|
||||
CURL_MEV_PS_HASH_SLOTS, mev_hash_conn_pollset_free);
|
||||
}
|
||||
|
||||
void Curl_multi_ev_cleanup(struct Curl_multi *multi)
|
||||
{
|
||||
Curl_hash_destroy(&multi->ev.sh_entries);
|
||||
Curl_uint_hash_destroy(&multi->ev.xfer_pollsets);
|
||||
Curl_hash_offt_destroy(&multi->ev.conn_pollsets);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue