mulit_ev: remove socket references on forget
No binary (build failed)
—
(log yok)
| @@ -131,6 +131,52 @@ static bool mev_sh_entry_conn_known(struct mev_sh_entry *e, | |
| return (e->conn == conn); | |
| } | |
| + | static void mev_pollset_dtor(const void *key, size_t klen, void *entry) |
| + | { |
| + | struct easy_pollset *ps = entry; |
| + | (void)key; |
| + | (void)klen; |
| + | if(ps) { |
| + | Curl_pollset_cleanup(ps); |
| + | curlx_free(ps); |
| + | } |
| + | } |
| + | |
| + | static struct easy_pollset *mev_add_new_conn_pollset(struct connectdata *conn) |
| + | { |
| + | struct easy_pollset *ps; |
| + | |
| + | ps = Curl_pollset_create(); |
| + | if(!ps) |
| + | return NULL; |
| + | if(Curl_conn_meta_set(conn, CURL_META_MEV_POLLSET, ps, mev_pollset_dtor)) |
| + | return NULL; |
| + | return ps; |
| + | } |
| + | |
| + | static struct easy_pollset *mev_add_new_xfer_pollset(struct Curl_easy *data) |
| + | { |
| + | struct easy_pollset *ps; |
| + | |
| + | ps = Curl_pollset_create(); |
| + | if(!ps) |
| + | return NULL; |
| + | if(Curl_meta_set(data, CURL_META_MEV_POLLSET, ps, mev_pollset_dtor)) |
| + | return NULL; |
| + | return ps; |
| + | } |
| + | |
| + | static struct easy_pollset *mev_get_last_pollset(struct Curl_easy *data, |
| + | struct connectdata *conn) |
| + | { |
| + | if(data) { |
| + | if(conn) |
| + | return Curl_conn_meta_get(conn, CURL_META_MEV_POLLSET); |
| + | return Curl_meta_get(data, CURL_META_MEV_POLLSET); |
| + | } |
| + | return NULL; |
| + | } |
| + | |
| static bool mev_sh_entry_xfer_add(struct mev_sh_entry *e, | |
| struct Curl_easy *data) | |
| { | |
| @@ -179,11 +225,30 @@ static CURLMcode mev_forget_socket(struct Curl_multi *multi, | |
| const char *cause) | |
| { | |
| struct mev_sh_entry *entry = mev_sh_entry_get(&multi->ev.sh_entries, s); | |
| + | uint32_t mid; |
| int rc = 0; | |
| if(!entry) /* we never knew or already forgot about this socket */ | |
| return CURLM_OK; | |
| + | /* Remove the socket from any pollset that is still registered. */ |
| + | if(Curl_uint32_spbset_first(&entry->xfers, &mid)) { |
| + | do { |
| + | struct Curl_easy *sdata = Curl_multi_get_easy(multi, mid); |
| + | if(sdata) { |
| + | struct easy_pollset *ps = mev_get_last_pollset(sdata, NULL); |
| + | if(ps) |
| + | Curl_pollset_remove(ps, s); |
| + | } |
| + | } while(Curl_uint32_spbset_next(&entry->xfers, mid, &mid)); |
| + | } |
| + | |
| + | if(entry->conn) { |
| + | struct easy_pollset *ps = mev_get_last_pollset(data, entry->conn); |
| + | if(ps) |
| + | Curl_pollset_remove(ps, s); |
| + | } |
| + | |
| /* We managed this socket before, tell the socket callback to forget it. */ | |
| if(entry->announced && multi->socket_cb) { | |
| struct Curl_mapi_guard guard; | |
| @@ -433,52 +498,6 @@ static CURLMcode mev_pollset_diff(struct Curl_multi *multi, | |
| return CURLM_OK; | |
| } | |
| - | static void mev_pollset_dtor(const void *key, size_t klen, void *entry) |
| - | { |
| - | struct easy_pollset *ps = entry; |
| - | (void)key; |
| - | (void)klen; |
| - | if(ps) { |
| - | Curl_pollset_cleanup(ps); |
| - | curlx_free(ps); |
| - | } |
| - | } |
| - | |
| - | static struct easy_pollset *mev_add_new_conn_pollset(struct connectdata *conn) |
| - | { |
| - | struct easy_pollset *ps; |
| - | |
| - | ps = Curl_pollset_create(); |
| - | if(!ps) |
| - | return NULL; |
| - | if(Curl_conn_meta_set(conn, CURL_META_MEV_POLLSET, ps, mev_pollset_dtor)) |
| - | return NULL; |
| - | return ps; |
| - | } |
| - | |
| - | static struct easy_pollset *mev_add_new_xfer_pollset(struct Curl_easy *data) |
| - | { |
| - | struct easy_pollset *ps; |
| - | |
| - | ps = Curl_pollset_create(); |
| - | if(!ps) |
| - | return NULL; |
| - | if(Curl_meta_set(data, CURL_META_MEV_POLLSET, ps, mev_pollset_dtor)) |
| - | return NULL; |
| - | return ps; |
| - | } |
| - | |
| - | static struct easy_pollset *mev_get_last_pollset(struct Curl_easy *data, |
| - | struct connectdata *conn) |
| - | { |
| - | if(data) { |
| - | if(conn) |
| - | return Curl_conn_meta_get(conn, CURL_META_MEV_POLLSET); |
| - | return Curl_meta_get(data, CURL_META_MEV_POLLSET); |
| - | } |
| - | return NULL; |
| - | } |
| - | |
| static CURLMcode mev_assess(struct Curl_multi *multi, | |
| struct Curl_easy *data, | |
| struct connectdata *conn) | |
| @@ -632,6 +632,23 @@ CURLcode Curl_pollset_set(struct Curl_easy *data, | |
| (!do_out ? CURL_POLL_OUT : 0)); | |
| } | |
| + | void Curl_pollset_remove(struct easy_pollset *ps, curl_socket_t sock) |
| + | { |
| + | unsigned int i; |
| + | for(i = 0; i < ps->n; ++i) { |
| + | if(ps->sockets[i] == sock) { |
| + | if((i + 1) < ps->n) { |
| + | memmove(&ps->sockets[i], &ps->sockets[i + 1], |
| + | (ps->n - (i + 1)) * sizeof(ps->sockets[0])); |
| + | memmove(&ps->actions[i], &ps->actions[i + 1], |
| + | (ps->n - (i + 1)) * sizeof(ps->actions[0])); |
| + | } |
| + | --ps->n; |
| + | return; |
| + | } |
| + | } |
| + | } |
| + | |
| /* | |
| * Return values: | |
| * -1 = error | |
| @@ -171,6 +171,8 @@ CURLcode Curl_pollset_set(struct Curl_easy *data, | |
| #define Curl_pollset_set_out_only(data, ps, sock) \ | |
| Curl_pollset_change(data, ps, sock, CURL_POLL_OUT, CURL_POLL_IN) | |
| + | void Curl_pollset_remove(struct easy_pollset *ps, curl_socket_t sock); |
| + | |
| /* return < = on error, 0 on timeout or how many sockets are ready */ | |
| int Curl_pollset_poll(struct Curl_easy *data, | |
| struct easy_pollset *ps, | |