Loading lib/http2.c +76 −0 Original line number Diff line number Diff line Loading @@ -2108,6 +2108,82 @@ CURLcode Curl_http2_switched(struct connectdata *conn, return CURLE_OK; } void Curl_http2_add_child(struct Curl_easy *parent, struct Curl_easy *child, bool exclusive) { struct Curl_http2_dep **tail; struct Curl_http2_dep *dep = calloc(1, sizeof(struct Curl_http2_dep)); dep->data = child; if(parent->set.stream_dependents && exclusive) { struct Curl_http2_dep *node = parent->set.stream_dependents; while(node) { node->data->set.stream_depends_on = child; node = node->next; } tail = &child->set.stream_dependents; while(*tail) tail = &(*tail)->next; DEBUGASSERT(!*tail); *tail = parent->set.stream_dependents; parent->set.stream_dependents = 0; } tail = &parent->set.stream_dependents; while(*tail) { (*tail)->data->set.stream_depends_e = FALSE; tail = &(*tail)->next; } DEBUGASSERT(!*tail); *tail = dep; child->set.stream_depends_on = parent; child->set.stream_depends_e = exclusive; } void Curl_http2_remove_child(struct Curl_easy *parent, struct Curl_easy *child) { struct Curl_http2_dep *last = 0; struct Curl_http2_dep *data = parent->set.stream_dependents; DEBUGASSERT(child->set.stream_depends_on == parent); while(data && data->data != child) { last = data; data = data->next; } DEBUGASSERT(data); if(data) { if(last) { last->next = data->next; } else { parent->set.stream_dependents = data->next; } free(data); } child->set.stream_depends_on = 0; child->set.stream_depends_e = FALSE; } void Curl_http2_cleanup_dependencies(struct Curl_easy *data) { while(data->set.stream_dependents) { struct Curl_easy *tmp = data->set.stream_dependents->data; Curl_http2_remove_child(data, tmp); if(data->set.stream_depends_on) Curl_http2_add_child(data->set.stream_depends_on, tmp, FALSE); } if(data->set.stream_depends_on) Curl_http2_remove_child(data->set.stream_depends_on, data); } #else /* !USE_NGHTTP2 */ /* Satisfy external references even if http2 is not compiled in. */ Loading lib/http2.h +8 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,11 @@ void Curl_http2_setup_conn(struct connectdata *conn); void Curl_http2_setup_req(struct Curl_easy *data); void Curl_http2_done(struct connectdata *conn, bool premature); CURLcode Curl_http2_done_sending(struct connectdata *conn); void Curl_http2_add_child(struct Curl_easy *parent, struct Curl_easy *child, bool exclusive); void Curl_http2_remove_child(struct Curl_easy *parent, struct Curl_easy *child); void Curl_http2_cleanup_dependencies(struct Curl_easy *data); #else /* USE_NGHTTP2 */ #define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL #define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL Loading @@ -65,6 +70,9 @@ CURLcode Curl_http2_done_sending(struct connectdata *conn); #define Curl_http2_init_userset(x) #define Curl_http2_done(x,y) #define Curl_http2_done_sending(x) #define Curl_http2_add_child(x, y, z) #define Curl_http2_remove_child(x, y) #define Curl_http2_cleanup_dependencies(x) #endif #endif /* HEADER_CURL_HTTP2_H */ Loading lib/url.c +6 −3 Original line number Diff line number Diff line Loading @@ -464,6 +464,7 @@ CURLcode Curl_close(struct Curl_easy *data) /* this destroys the channel and we cannot use it anymore after this */ Curl_resolver_cleanup(data->state.resolver); Curl_http2_cleanup_dependencies(data); Curl_convert_close(data); /* No longer a dirty share, if it exists */ Loading Loading @@ -2847,9 +2848,11 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, return CURLE_NOT_BUILT_IN; #else struct Curl_easy *dep = va_arg(param, struct Curl_easy *); if(dep && GOOD_EASY_HANDLE(dep)) { data->set.stream_depends_on = dep; data->set.stream_depends_e = (option == CURLOPT_STREAM_DEPENDS_E); if(!dep || GOOD_EASY_HANDLE(dep)) { if(data->set.stream_depends_on) { Curl_http2_remove_child(data->set.stream_depends_on, data); } Curl_http2_add_child(dep, data, (option == CURLOPT_STREAM_DEPENDS_E)); } break; #endif Loading lib/urldata.h +7 −0 Original line number Diff line number Diff line Loading @@ -1280,6 +1280,11 @@ struct auth { be RFC compliant */ }; struct Curl_http2_dep { struct Curl_http2_dep *next; struct Curl_easy *data; }; struct UrlState { /* Points to the connection cache */ Loading Loading @@ -1747,6 +1752,8 @@ struct UserDefined { struct Curl_easy *stream_depends_on; bool stream_depends_e; /* set or don't set the Exclusive bit */ int stream_weight; struct Curl_http2_dep *stream_dependents; }; struct Names { Loading Loading
lib/http2.c +76 −0 Original line number Diff line number Diff line Loading @@ -2108,6 +2108,82 @@ CURLcode Curl_http2_switched(struct connectdata *conn, return CURLE_OK; } void Curl_http2_add_child(struct Curl_easy *parent, struct Curl_easy *child, bool exclusive) { struct Curl_http2_dep **tail; struct Curl_http2_dep *dep = calloc(1, sizeof(struct Curl_http2_dep)); dep->data = child; if(parent->set.stream_dependents && exclusive) { struct Curl_http2_dep *node = parent->set.stream_dependents; while(node) { node->data->set.stream_depends_on = child; node = node->next; } tail = &child->set.stream_dependents; while(*tail) tail = &(*tail)->next; DEBUGASSERT(!*tail); *tail = parent->set.stream_dependents; parent->set.stream_dependents = 0; } tail = &parent->set.stream_dependents; while(*tail) { (*tail)->data->set.stream_depends_e = FALSE; tail = &(*tail)->next; } DEBUGASSERT(!*tail); *tail = dep; child->set.stream_depends_on = parent; child->set.stream_depends_e = exclusive; } void Curl_http2_remove_child(struct Curl_easy *parent, struct Curl_easy *child) { struct Curl_http2_dep *last = 0; struct Curl_http2_dep *data = parent->set.stream_dependents; DEBUGASSERT(child->set.stream_depends_on == parent); while(data && data->data != child) { last = data; data = data->next; } DEBUGASSERT(data); if(data) { if(last) { last->next = data->next; } else { parent->set.stream_dependents = data->next; } free(data); } child->set.stream_depends_on = 0; child->set.stream_depends_e = FALSE; } void Curl_http2_cleanup_dependencies(struct Curl_easy *data) { while(data->set.stream_dependents) { struct Curl_easy *tmp = data->set.stream_dependents->data; Curl_http2_remove_child(data, tmp); if(data->set.stream_depends_on) Curl_http2_add_child(data->set.stream_depends_on, tmp, FALSE); } if(data->set.stream_depends_on) Curl_http2_remove_child(data->set.stream_depends_on, data); } #else /* !USE_NGHTTP2 */ /* Satisfy external references even if http2 is not compiled in. */ Loading
lib/http2.h +8 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,11 @@ void Curl_http2_setup_conn(struct connectdata *conn); void Curl_http2_setup_req(struct Curl_easy *data); void Curl_http2_done(struct connectdata *conn, bool premature); CURLcode Curl_http2_done_sending(struct connectdata *conn); void Curl_http2_add_child(struct Curl_easy *parent, struct Curl_easy *child, bool exclusive); void Curl_http2_remove_child(struct Curl_easy *parent, struct Curl_easy *child); void Curl_http2_cleanup_dependencies(struct Curl_easy *data); #else /* USE_NGHTTP2 */ #define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL #define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL Loading @@ -65,6 +70,9 @@ CURLcode Curl_http2_done_sending(struct connectdata *conn); #define Curl_http2_init_userset(x) #define Curl_http2_done(x,y) #define Curl_http2_done_sending(x) #define Curl_http2_add_child(x, y, z) #define Curl_http2_remove_child(x, y) #define Curl_http2_cleanup_dependencies(x) #endif #endif /* HEADER_CURL_HTTP2_H */ Loading
lib/url.c +6 −3 Original line number Diff line number Diff line Loading @@ -464,6 +464,7 @@ CURLcode Curl_close(struct Curl_easy *data) /* this destroys the channel and we cannot use it anymore after this */ Curl_resolver_cleanup(data->state.resolver); Curl_http2_cleanup_dependencies(data); Curl_convert_close(data); /* No longer a dirty share, if it exists */ Loading Loading @@ -2847,9 +2848,11 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, return CURLE_NOT_BUILT_IN; #else struct Curl_easy *dep = va_arg(param, struct Curl_easy *); if(dep && GOOD_EASY_HANDLE(dep)) { data->set.stream_depends_on = dep; data->set.stream_depends_e = (option == CURLOPT_STREAM_DEPENDS_E); if(!dep || GOOD_EASY_HANDLE(dep)) { if(data->set.stream_depends_on) { Curl_http2_remove_child(data->set.stream_depends_on, data); } Curl_http2_add_child(dep, data, (option == CURLOPT_STREAM_DEPENDS_E)); } break; #endif Loading
lib/urldata.h +7 −0 Original line number Diff line number Diff line Loading @@ -1280,6 +1280,11 @@ struct auth { be RFC compliant */ }; struct Curl_http2_dep { struct Curl_http2_dep *next; struct Curl_easy *data; }; struct UrlState { /* Points to the connection cache */ Loading Loading @@ -1747,6 +1752,8 @@ struct UserDefined { struct Curl_easy *stream_depends_on; bool stream_depends_e; /* set or don't set the Exclusive bit */ int stream_weight; struct Curl_http2_dep *stream_dependents; }; struct Names { Loading