From fdfe590a4187e56b168012917b2c68e975ecc628 Mon Sep 17 00:00:00 2001 From: Tomas Krizek Date: Mon, 8 Mar 2021 12:19:29 +0100 Subject: [PATCH] daemon/http: optimize code by using trie instead of array macros --- daemon/http.c | 95 ++++++++++++++++++--------------------------------- daemon/http.h | 2 +- 2 files changed, 35 insertions(+), 62 deletions(-) diff --git a/daemon/http.c b/daemon/http.c index 802d96ba7..313808706 100644 --- a/daemon/http.c +++ b/daemon/http.c @@ -45,6 +45,24 @@ struct http_data { uv_write_t *req; }; +static void http_stream_status_free(struct http_stream_status *stat) +{ + if (!stat) + return; + + free(stat->err_msg); + stat->err_msg = NULL; + free(stat); +} + +static int status_free(trie_val_t *stat, void *null) +{ + assert(stat); + http_stream_status_free(*stat); + return 0; +} + + /* * Write HTTP/2 protocol data to underlying transport layer. */ @@ -95,9 +113,6 @@ static int send_padding(struct http_ctx *ctx, uint8_t padlen) return 0; } -static int http_status_remove(struct http_ctx *ctx, struct http_stream_status * stat); -static struct http_stream_status * http_status_get(struct http_ctx *ctx, int32_t stream_id); - /* * Write entire DATA frame to underlying transport layer. * @@ -131,8 +146,6 @@ static int send_data_callback(nghttp2_session *h2, nghttp2_frame *frame, const u if (ret < 0) return NGHTTP2_ERR_CALLBACK_FAILURE; - http_status_remove(ctx, http_status_get(ctx, frame->hd.stream_id)); - return 0; } @@ -168,49 +181,6 @@ static ssize_t read_callback(nghttp2_session *h2, int32_t stream_id, uint8_t *bu return send; } -/* - * Get pointer to stream status. - */ -static struct http_stream_status * http_status_get(struct http_ctx *ctx, int32_t stream_id) -{ - assert(ctx); - struct http_stream_status *stat = NULL; - - if (ctx->current_stream && ctx->current_stream->stream_id == stream_id) - return ctx->current_stream; - - - for (size_t idx = 0; idx < ctx->stream_status.len; ++idx) { - stat = ctx->stream_status.at[idx]; - if (stat->stream_id == stream_id) - return stat; - } - return NULL; -} - -/* - * Remove error stream status from list - */ -static int http_status_remove(struct http_ctx *ctx, struct http_stream_status * stat) -{ - if (!stat) - return 0; - - free(stat->err_msg); - stat->err_msg = NULL; - - size_t idx; - for (idx = 0; idx < ctx->stream_status.len; ++idx) { - if (stat->stream_id == ctx->stream_status.at[idx]->stream_id) { - array_del(ctx->stream_status, idx); - free(stat); - break; - } - } - - return 0; -} - /* * Send http error status code. */ @@ -219,10 +189,11 @@ static int send_err_status(struct http_ctx *ctx, int32_t stream_id) int ret; int status_len; nghttp2_data_provider prov; - struct http_stream_status *stat = http_status_get(ctx, stream_id); + trie_val_t *stat_p = trie_get_try(ctx->stream_status, (char *)&stream_id, sizeof(stream_id)); - if(!stat) + if (!stat_p || !*stat_p) return kr_error(EINVAL); + struct http_stream_status *stat = *stat_p; prov.source.ptr = NULL; prov.read_callback = read_callback; @@ -265,7 +236,8 @@ static int send_err_status(struct http_ctx *ctx, int32_t stream_id) static struct http_stream_status * set_error_status(struct http_ctx *ctx, int32_t stream_id, int status, const char *const status_msg) { - struct http_stream_status *stat = http_status_get(ctx, stream_id); + trie_val_t *stat_p = trie_get_ins(ctx->stream_status, (char *)&stream_id, sizeof(stream_id)); + struct http_stream_status *stat = *stat_p; if (stat && stat->err_status != 200) return stat; @@ -275,12 +247,7 @@ static struct http_stream_status * set_error_status(struct http_ctx *ctx, int32_ if (!stat) return NULL; - // push to end of array - if (array_push(ctx->stream_status, stat) < 0) { - free(stat); - return NULL; - } - + *stat_p = stat; stat->err_msg = NULL; } stat->stream_id = stream_id; @@ -711,12 +678,19 @@ static void on_pkt_write(struct http_data *data, int status) static int on_stream_close_callback(nghttp2_session *h2, int32_t stream_id, uint32_t error_code, void *user_data) { + struct http_ctx *ctx = (struct http_ctx *)user_data; struct http_data *data; + struct http_stream_status *stat; + int ret; data = nghttp2_session_get_stream_user_data(h2, stream_id); if (data) on_pkt_write(data, error_code == 0 ? 0 : kr_error(EIO)); + ret = trie_del(ctx->stream_status, (char *)&stream_id, sizeof(stream_id), (trie_val_t *)&stat); + if (ret == 0) + http_stream_status_free(stat); + return 0; } @@ -758,7 +732,7 @@ struct http_ctx* http_new(struct session *session, http_send_callback send_cb) ctx->current_method = HTTP_METHOD_NONE; ctx->uri_path = NULL; ctx->content_type = NULL; - array_init(ctx->stream_status); + ctx->stream_status = trie_create(NULL); nghttp2_session_server_new(&ctx->h2, callbacks, ctx); @@ -920,9 +894,8 @@ void http_free(struct http_ctx *ctx) if (!ctx) return; - while(ctx->stream_status.len) - http_status_remove(ctx, ctx->stream_status.at[0]); - array_clear(ctx->stream_status); + trie_apply(ctx->stream_status, status_free, NULL); + trie_free(ctx->stream_status); queue_deinit(ctx->streams); nghttp2_session_del(ctx->h2); diff --git a/daemon/http.h b/daemon/http.h index 114f261e3..2f9c84529 100644 --- a/daemon/http.h +++ b/daemon/http.h @@ -51,7 +51,7 @@ struct http_ctx { uint8_t *buf; /* Part of the wire_buf that belongs to current HTTP/2 stream. */ ssize_t buf_pos; ssize_t buf_size; - array_t(struct http_stream_status*) stream_status; + trie_t *stream_status; struct http_stream_status *current_stream; }; -- 2.47.2