view src/core/ngx_queue.c @ 6153:4f6efabcb09b

The "reuseport" option of the "listen" directive. When configured, an individual listen socket on a given address is created for each worker process. This allows to reduce in-kernel lock contention on configurations with high accept rates, resulting in better performance. As of now it works on Linux and DragonFly BSD. Note that on Linux incoming connection requests are currently tied up to a specific listen socket, and if some sockets are closed, connection requests will be reset, see https://lwn.net/Articles/542629/. With nginx, this may happen if the number of worker processes is reduced. There is no such problem on DragonFly BSD. Based on previous work by Sepherosa Ziehau and Yingqi Lu.
author Maxim Dounin <mdounin@mdounin.ru>
date Wed, 20 May 2015 15:51:56 +0300
parents d620f497c50f
children 3038bd4d7816
line wrap: on
line source


/*
 * Copyright (C) Igor Sysoev
 * Copyright (C) Nginx, Inc.
 */


#include <ngx_config.h>
#include <ngx_core.h>


/*
 * find the middle queue element if the queue has odd number of elements
 * or the first element of the queue's second part otherwise
 */

ngx_queue_t *
ngx_queue_middle(ngx_queue_t *queue)
{
    ngx_queue_t  *middle, *next;

    middle = ngx_queue_head(queue);

    if (middle == ngx_queue_last(queue)) {
        return middle;
    }

    next = ngx_queue_head(queue);

    for ( ;; ) {
        middle = ngx_queue_next(middle);

        next = ngx_queue_next(next);

        if (next == ngx_queue_last(queue)) {
            return middle;
        }

        next = ngx_queue_next(next);

        if (next == ngx_queue_last(queue)) {
            return middle;
        }
    }
}


/* the stable insertion sort */

void
ngx_queue_sort(ngx_queue_t *queue,
    ngx_int_t (*cmp)(const ngx_queue_t *, const ngx_queue_t *))
{
    ngx_queue_t  *q, *prev, *next;

    q = ngx_queue_head(queue);

    if (q == ngx_queue_last(queue)) {
        return;
    }

    for (q = ngx_queue_next(q); q != ngx_queue_sentinel(queue); q = next) {

        prev = ngx_queue_prev(q);
        next = ngx_queue_next(q);

        ngx_queue_remove(q);

        do {
            if (cmp(prev, q) <= 0) {
                break;
            }

            prev = ngx_queue_prev(prev);

        } while (prev != ngx_queue_sentinel(queue));

        ngx_queue_insert_after(prev, q);
    }
}