diff options
author | Andrei Belov <defan@nginx.com> | 2019-11-14 19:29:00 +0300 |
---|---|---|
committer | Andrei Belov <defan@nginx.com> | 2019-11-14 19:29:00 +0300 |
commit | 7630539c44fcb188bba03a65af34e952a81f2f38 (patch) | |
tree | 2c80f0cd315cae8079a39ba98ed89e02b5e1931a /src/nxt_sendbuf.c | |
parent | 70c9f18b6e8b25850bce8eb1edba4d100c3e55d2 (diff) | |
parent | 0a27f137de776925a24406cf6961c550824c63a0 (diff) | |
download | unit-7630539c44fcb188bba03a65af34e952a81f2f38.tar.gz unit-7630539c44fcb188bba03a65af34e952a81f2f38.tar.bz2 |
Merged with the default branch.1.13.0-1
Diffstat (limited to 'src/nxt_sendbuf.c')
-rw-r--r-- | src/nxt_sendbuf.c | 53 |
1 files changed, 45 insertions, 8 deletions
diff --git a/src/nxt_sendbuf.c b/src/nxt_sendbuf.c index 16fe4724..94f8e9eb 100644 --- a/src/nxt_sendbuf.c +++ b/src/nxt_sendbuf.c @@ -9,6 +9,8 @@ static nxt_bool_t nxt_sendbuf_copy(nxt_buf_mem_t *bm, nxt_buf_t *b, size_t *copied); +static nxt_buf_t *nxt_sendbuf_coalesce_completion(nxt_task_t *task, + nxt_work_queue_t *wq, nxt_buf_t *start); nxt_uint_t @@ -380,15 +382,11 @@ nxt_sendbuf_completion(nxt_task_t *task, nxt_work_queue_t *wq, nxt_buf_t *b) { while (b != NULL) { - nxt_prefetch(b->next); - if (!nxt_buf_is_sync(b) && nxt_buf_used_size(b) != 0) { break; } - nxt_work_queue_add(wq, b->completion_handler, task, b, b->parent); - - b = b->next; + b = nxt_sendbuf_coalesce_completion(task, wq, b); } return b; @@ -399,10 +397,49 @@ void nxt_sendbuf_drain(nxt_task_t *task, nxt_work_queue_t *wq, nxt_buf_t *b) { while (b != NULL) { - nxt_prefetch(b->next); + b = nxt_sendbuf_coalesce_completion(task, wq, b); + } +} - nxt_work_queue_add(wq, b->completion_handler, task, b, b->parent); - b = b->next; +static nxt_buf_t * +nxt_sendbuf_coalesce_completion(nxt_task_t *task, nxt_work_queue_t *wq, + nxt_buf_t *start) +{ + nxt_buf_t *b, *next, **last, *rest, **last_rest; + nxt_work_handler_t handler; + + rest = NULL; + last_rest = &rest; + last = &start->next; + b = start; + handler = b->completion_handler; + + for ( ;; ) { + next = b->next; + if (next == NULL) { + break; + } + + b->next = NULL; + b = next; + + if (!nxt_buf_is_sync(b) && nxt_buf_used_size(b) != 0) { + *last_rest = b; + break; + } + + if (handler == b->completion_handler) { + *last = b; + last = &b->next; + + } else { + *last_rest = b; + last_rest = &b->next; + } } + + nxt_work_queue_add(wq, handler, task, start, start->parent); + + return rest; } |