From 8c33de2bf97503f0fda31e6f1d185bb018e9dceb Mon Sep 17 00:00:00 2001 From: ruti <> Date: Sun, 9 Feb 2025 01:07:57 +0300 Subject: [PATCH] Faster buffer retrieval --- conev.c | 47 +++++++++++++++++++++++++---------------------- conev.h | 14 +++++++++----- extend.c | 24 +++++++++++------------- proxy.c | 32 ++++++++++++++++++-------------- 4 files changed, 63 insertions(+), 54 deletions(-) diff --git a/conev.c b/conev.c index 9caea9c..8278162 100644 --- a/conev.c +++ b/conev.c @@ -93,11 +93,11 @@ void del_event(struct poolhd *pool, struct eval *val) epoll_ctl(pool->efd, EPOLL_CTL_DEL, val->fd, 0); #endif if (val->buff) { - buff_unlock(val->buff); + buff_push(pool, val->buff); val->buff = 0; } if (val->sq_buff) { - buff_unlock(val->sq_buff); + buff_push(pool, val->sq_buff); val->sq_buff = 0; } close(val->fd); @@ -131,12 +131,9 @@ void del_event(struct poolhd *pool, struct eval *val) void destroy_pool(struct poolhd *pool) { - for (int x = 0; x < pool->count; x++) { - struct eval *val = pool->links[x]; - if (val->fd) { - close(val->fd); - val->fd = 0; - } + while (pool->count) { + struct eval *val = pool->links[0]; + del_event(pool, val); } free(pool->items); free(pool->links); @@ -332,16 +329,12 @@ void loop_event(struct poolhd *pool) } -struct buffer *buff_get(struct buffer *root, size_t size) +struct buffer *buff_pop(struct poolhd *pool, size_t size) { - struct buffer *prev = root; - - while (root) { - if (!root->lock) { - return root; - } - prev = root; - root = root->next; + struct buffer *root = pool->root_buff; + if (root) { + pool->root_buff = root->next; + return root; } struct buffer *buff = malloc(sizeof(struct buffer) + size); if (!buff) { @@ -352,20 +345,30 @@ struct buffer *buff_get(struct buffer *root, size_t size) memset(buff, 0, sizeof(struct buffer)); buff->size = size; - - if (prev) { - prev->next = buff; - } return buff; } +void buff_push(struct poolhd *pool, struct buffer *buff) +{ + if (!buff) { + return; + } + buff->lock = 0; + buff->offset = 0; + buff->next = pool->root_buff; + pool->root_buff = buff; +} + + void buff_destroy(struct buffer *root) { - while (root) { + int i = 0; + for (; root; i++) { struct buffer *c = root; root = root->next; free(c); } + LOG(LOG_S, "buffers count: %d\n", i); } diff --git a/conev.h b/conev.h index 6962efc..5b38128 100644 --- a/conev.h +++ b/conev.h @@ -117,12 +117,16 @@ void remove_timer(struct poolhd *pool, struct eval *val); void loop_event(struct poolhd *pool); -struct buffer *buff_get(struct buffer *root, size_t size); +struct buffer *buff_pop(struct poolhd *pool, size_t size); + +void buff_push(struct poolhd *pool, struct buffer *buff); void buff_destroy(struct buffer *root); -#define buff_unlock(buff) \ - buff->lock = 0; \ - buff->offset = 0; - +static struct buffer *buff_ppop(struct poolhd *pool, size_t size) +{ + struct buffer *b = buff_pop(pool, size); + if (b) buff_push(pool, b); + return b; +} #endif diff --git a/extend.c b/extend.c index 8c4d147..24b18af 100644 --- a/extend.c +++ b/extend.c @@ -165,11 +165,12 @@ static int reconnect(struct poolhd *pool, struct eval *val, int m) client->attempt = m; client->cache = 1; - struct buffer *buff = buff_get(pool->root_buff, client->sq_buff->size); - buff->lock = client->sq_buff->lock; - memcpy(buff->data, client->sq_buff->data, buff->lock); + if (!client->buff) { + client->buff = buff_pop(pool, client->sq_buff->size); + } + client->buff->lock = client->sq_buff->lock; + memcpy(client->buff->data, client->sq_buff->data, client->buff->lock); - client->buff = buff; client->buff->offset = 0; client->round_sent = 0; return 0; @@ -349,9 +350,9 @@ static int on_response(struct poolhd *pool, struct eval *val, } -static inline void free_first_req(struct eval *client) +static inline void free_first_req(struct poolhd *pool, struct eval *client) { - buff_unlock(client->sq_buff); + buff_push(pool, client->sq_buff); client->sq_buff = 0; } @@ -483,17 +484,14 @@ ssize_t tcp_recv_hook(struct poolhd *pool, && (val->sq_buff || val->recv_count == n)) { if (!val->sq_buff) { - buff->lock = 1; - { - struct buffer *b = buff_get(pool->root_buff, buff->size); - val->sq_buff = b; + if (!(val->sq_buff = buff_pop(pool, buff->size))) { + return -1; } - buff->lock = 0; } val->sq_buff->lock += n; if ((size_t )val->sq_buff->lock >= val->sq_buff->size) { - free_first_req(val); + free_first_req(pool, val); } else { memcpy(val->sq_buff->data + val->sq_buff->lock - n, buff->data, n); @@ -503,7 +501,7 @@ ssize_t tcp_recv_hook(struct poolhd *pool, if (on_response(pool, val, buff->data, n) == 0) { return 0; } - free_first_req(val->pair); + free_first_req(pool, val->pair); int m = val->pair->attempt; if (val->pair->cache && cache_add(&val->addr, m) < 0) { diff --git a/proxy.c b/proxy.c index c1da781..68512ce 100644 --- a/proxy.c +++ b/proxy.c @@ -656,7 +656,7 @@ int on_tunnel(struct poolhd *pool, struct eval *val, int etype) val = pair; pair = val->pair; } - if (val->buff && val->buff->lock) { + if (val->buff) { if (etype & POLLHUP) { return -1; } @@ -671,7 +671,7 @@ int on_tunnel(struct poolhd *pool, struct eval *val, int etype) val->buff->offset += sn; return 0; } - buff_unlock(val->buff); + buff_push(pool, val->buff); val->buff = 0; if (mod_etype(pool, val, POLLIN) || @@ -680,7 +680,11 @@ int on_tunnel(struct poolhd *pool, struct eval *val, int etype) return -1; } } - struct buffer *buff = buff_get(pool->root_buff, params.bfsize); + struct buffer *buff = buff_pop(pool, params.bfsize); + if (!buff) { + return -1; + } + val->buff = buff; do { n = tcp_recv_hook(pool, val, buff); //if (n < 0 && get_e() == EAGAIN) { @@ -698,7 +702,6 @@ int on_tunnel(struct poolhd *pool, struct eval *val, int etype) if (sn < n) { LOG(LOG_S, "send: %zd != %zd (fd=%d)\n", sn, n, pair->fd); - val->buff = buff; buff->lock = n; buff->offset = sn; @@ -707,17 +710,21 @@ int on_tunnel(struct poolhd *pool, struct eval *val, int etype) uniperror("mod_etype"); return -1; } - break; + return 0; } } while (n == (ssize_t )buff->size); + buff_push(pool, val->buff); + val->buff = 0; return 0; } int on_udp_tunnel(struct poolhd *pool, struct eval *val, int et) { - struct buffer *buff = buff_get(pool->root_buff, params.bfsize); - + struct buffer *buff = buff_ppop(pool, params.bfsize); + if (!buff) { + return -1; + } char *data = buff->data; size_t data_len = buff->size; @@ -803,8 +810,10 @@ int on_udp_tunnel(struct poolhd *pool, struct eval *val, int et) int on_request(struct poolhd *pool, struct eval *val, int et) { union sockaddr_u dst = {0}; - struct buffer *buff = buff_get(pool->root_buff, params.bfsize); - + struct buffer *buff = buff_ppop(pool, params.bfsize); + if (!buff) { + return -1; + } ssize_t n = recv(val->fd, buff->data, buff->size, 0); if (n < 1) { if (n) uniperror("ss recv"); @@ -936,11 +945,6 @@ int start_event_loop(int srvfd) close(srvfd); return -1; } - pool->root_buff = buff_get(0, params.bfsize); - if (!pool->root_buff) { - destroy_pool(pool); - return -1; - } loop_event(pool); LOG(LOG_S, "exit\n");