
/*
 * Copyright (C) Igor Sysoev
 */


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


static void ngx_close_accepted_socket(ngx_socket_t s, ngx_log_t *log);
static u_char *ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len);


void
ngx_event_accept(ngx_event_t *ev)
{
    ngx_uint_t         instance;
#if 0
    ngx_uint_t         accepted;
#endif
    socklen_t          len;
    struct sockaddr   *sa;
    ngx_err_t          err;
    ngx_log_t         *log;
    ngx_pool_t        *pool;
    ngx_socket_t       s;
    ngx_event_t       *rev, *wev;
    ngx_connection_t  *c, *ls;
    ngx_event_conf_t  *ecf;

    ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module);

    if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
        ev->available = 1;

    } else if (!(ngx_event_flags & NGX_USE_KQUEUE_EVENT)) {
        ev->available = ecf->multi_accept;
    }

    ls = ev->data;

    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
                   "accept on %V, ready: %d",
                   &ls->listening->addr_text, ev->available);

    ev->ready = 0;
    pool = NULL;
#if 0
    accepted = 0;
#endif

    do {

        if (pool == NULL) {

            /*
             * Create the pool before accept() to avoid the copying of
             * the sockaddr.  Although accept() can fail it is uncommon
             * case and besides the pool can be got from the free pool list.
             */

            pool = ngx_create_pool(ls->listening->pool_size, ev->log);
            if (pool == NULL) {
                return;
            }
        }

        sa = ngx_palloc(pool, ls->listening->socklen);
        if (sa == NULL) {
            ngx_destroy_pool(pool);
            return;
        }

        log = ngx_palloc(pool, sizeof(ngx_log_t));
        if (log == NULL) {
            ngx_destroy_pool(pool);
            return;
        }

        ngx_memcpy(log, ls->log, sizeof(ngx_log_t));
        pool->log = log;

        log->data = &ls->listening->addr_text;
        log->handler = ngx_accept_log_error;

        len = ls->listening->socklen;

        s = accept(ls->fd, sa, &len);

        if (s == -1) {
            err = ngx_socket_errno;

            if (err == NGX_EAGAIN) {
#if 0
                if (!(ngx_event_flags & NGX_USE_RTSIG_EVENT))
                {
                    ngx_log_error(NGX_LOG_NOTICE, log, err,
                                  "EAGAIN after %d accepted connection(s)",
                                  accepted);
                }
#endif

                ngx_destroy_pool(pool);
                return;
            }

            ngx_log_error(NGX_LOG_ALERT, ev->log, err,
                          "accept() on %V failed", &ls->listening->addr_text);

            if (err == NGX_ECONNABORTED) {
                if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
                    ev->available--;
                }

                if (ev->available) {
                    /* reuse the previously allocated pool */
                    continue;
                }
            }

            ngx_destroy_pool(pool);
            return;
        }

#if (NGX_STAT_STUB)
        ngx_atomic_inc(ngx_stat_accepted);
        ngx_atomic_inc(ngx_stat_active);
#endif

        ngx_accept_disabled = (ngx_uint_t) s + NGX_ACCEPT_THRESHOLD
                                                            - ecf->connections;

        /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */

        if ((ngx_uint_t) s >= ecf->connections) {

            ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
                          "accept() on %V returned socket #%d while "
                          "only %d connections was configured, "
                          "closing the connection",
                          &ls->listening->addr_text, s, ecf->connections);

            ngx_close_accepted_socket(s, log);
            ngx_destroy_pool(pool);
            return;
        }

        /* set a blocking mode for aio and non-blocking mode for others */

        if (ngx_inherited_nonblocking) {
            if ((ngx_event_flags & NGX_USE_AIO_EVENT)) {
                if (ngx_blocking(s) == -1) {
                    ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
                                  ngx_blocking_n " failed");

                    ngx_close_accepted_socket(s, log);
                    ngx_destroy_pool(pool);
                    return;
                }
            }

        } else {
            if (!(ngx_event_flags & (NGX_USE_AIO_EVENT|NGX_USE_RTSIG_EVENT))) {
                if (ngx_nonblocking(s) == -1) {
                    ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
                                  ngx_nonblocking_n " failed");

                    ngx_close_accepted_socket(s, log);
                    ngx_destroy_pool(pool);
                    return;
                }
            }
        }

#if (NGX_WIN32)
        /*
         * Winsock assignes a socket number divisible by 4
         * so to find a connection we divide a socket number by 4.
         */

        if (s % 4) {
            ngx_log_error(NGX_LOG_EMERG, ev->log, 0,
                          "accept() on %V returned socket #%d, "
                          "not divisible by 4",
                          &ls->listening->addr_text, s);
            exit(1);
        }

        c = &ngx_cycle->connections[s / 4];
        rev = &ngx_cycle->read_events[s / 4];
        wev = &ngx_cycle->write_events[s / 4];
#else
        c = &ngx_cycle->connections[s];
        rev = &ngx_cycle->read_events[s];
        wev = &ngx_cycle->write_events[s];
#endif

        instance = rev->instance;

#if (NGX_THREADS)

        if (*(&c->lock)) {
            ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
                           "spinlock in accept, fd:%", s);
            ngx_spinlock(&c->lock, 1000);
            ngx_unlock(&c->lock);
        }

#endif

        ngx_memzero(rev, sizeof(ngx_event_t));
        ngx_memzero(wev, sizeof(ngx_event_t));
        ngx_memzero(c, sizeof(ngx_connection_t));

        c->pool = pool;

        c->listening = ls->listening;
        c->sockaddr = sa;
        c->socklen = len;

        rev->instance = !instance;
        wev->instance = !instance;

        rev->index = NGX_INVALID_INDEX;
        wev->index = NGX_INVALID_INDEX;

        rev->data = c;
        wev->data = c;

        c->read = rev;
        c->write = wev;

        c->fd = s;
        c->unexpected_eof = 1;

        wev->write = 1;
        wev->ready = 1;

        if (ngx_event_flags & (NGX_USE_AIO_EVENT|NGX_USE_RTSIG_EVENT)) {
            /* rtsig, aio, iocp */
            rev->ready = 1;
        }

        if (ev->deferred_accept) {
            rev->ready = 1;
        }

        c->ctx = ls->ctx;
        c->servers = ls->servers;

        c->recv = ngx_recv;
        c->send_chain = ngx_send_chain;

        c->log = log;
        rev->log = log;
        wev->log = log;

        /*
         * TODO: MT: - atomic increment (x86: lock xadd)
         *             or protection by critical section or light mutex
         *
         * TODO: MP: - allocated in a shared memory
         *           - atomic increment (x86: lock xadd)
         *             or protection by critical section or light mutex
         */

        c->number = ngx_atomic_inc(ngx_connection_counter);

#if (NGX_STAT_STUB)
        ngx_atomic_inc(ngx_stat_handled);
#endif

#if (NGX_THREADS)
        rev->lock = &c->lock;
        wev->lock = &c->lock;
        rev->own_lock = &c->lock;
        wev->own_lock = &c->lock;
#endif

        ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
                       "accept: fd:%d c:%d", s, c->number);

        if (c->listening->addr_ntop) {
            c->addr_text.data = ngx_palloc(c->pool,
                                           c->listening->addr_text_max_len);
            if (c->addr_text.data == NULL) {
                ngx_close_accepted_socket(s, log);
                ngx_destroy_pool(pool);
                return;
            }
    
            c->addr_text.len = ngx_sock_ntop(c->listening->family, c->sockaddr,
                                             c->addr_text.data,
                                             c->listening->addr_text_max_len);
            if (c->addr_text.len == 0) {
                ngx_close_accepted_socket(s, log);
                ngx_destroy_pool(pool);
                return;
            }
        }

#if (NGX_DEBUG)
        {

        uint32_t            *addr;
        in_addr_t            i;
        struct sockaddr_in  *sin;

        sin = (struct sockaddr_in *) sa;
        addr = ecf->debug_connection.elts;
        for (i = 0; i < ecf->debug_connection.nelts; i++) {
            if (addr[i] == sin->sin_addr.s_addr) {
                log->log_level = NGX_LOG_DEBUG_CONNECTION|NGX_LOG_DEBUG_ALL;
                break;
            }
        }

        }
#endif

        if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) {
            if (ngx_add_conn(c) == NGX_ERROR) {
                ngx_close_accepted_socket(s, log);
                ngx_destroy_pool(pool);
                return;
            }
        }

        pool = NULL;

        log->data = NULL;
        log->handler = NULL;

        ls->listening->handler(c);

        if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
            ev->available--;
        }

#if 0
        accepted++;
#endif

    } while (ev->available);
}


ngx_int_t
ngx_trylock_accept_mutex(ngx_cycle_t *cycle)
{
    if (*ngx_accept_mutex == 0
        && ngx_atomic_cmp_set(ngx_accept_mutex, 0, ngx_pid))
    {
        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                       "accept mutex locked");

        if (!ngx_accept_mutex_held) {
            if (ngx_enable_accept_events(cycle) == NGX_ERROR) {
                *ngx_accept_mutex = 0;
                return NGX_ERROR;
            }

            ngx_accept_mutex_held = 1;
        }

        return NGX_OK;
    }

    if (ngx_accept_mutex_held) {
        if (ngx_disable_accept_events(cycle) == NGX_ERROR) {
            return NGX_ERROR;
        }

        ngx_accept_mutex_held = 0;
    }

    return NGX_OK;
}


ngx_int_t
ngx_enable_accept_events(ngx_cycle_t *cycle)
{
    ngx_uint_t        i;
    ngx_listening_t  *s;

    s = cycle->listening.elts;
    for (i = 0; i < cycle->listening.nelts; i++) {

        /*
         * we do not need to handle the Winsock sockets here (divide a socket
         * number by 4) because this function would never called
         * in the Winsock environment
         */

        if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
            if (ngx_add_conn(&cycle->connections[s[i].fd]) == NGX_ERROR) {
                return NGX_ERROR;
            }

        } else {
            if (ngx_add_event(&cycle->read_events[s[i].fd], NGX_READ_EVENT, 0)
                                                                  == NGX_ERROR)
            {
                return NGX_ERROR;
            }
        }
    }

    return NGX_OK;
}


ngx_int_t
ngx_disable_accept_events(ngx_cycle_t *cycle)
{
    ngx_uint_t        i;
    ngx_listening_t  *s;

    s = cycle->listening.elts;
    for (i = 0; i < cycle->listening.nelts; i++) {

        /*
         * we do not need to handle the Winsock sockets here (divide a socket
         * number by 4) because this function would never called
         * in the Winsock environment
         */

        if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
            if (!cycle->connections[s[i].fd].read->active) {
                continue;
            }

            if (ngx_del_conn(&cycle->connections[s[i].fd], NGX_DISABLE_EVENT)
                                                                  == NGX_ERROR)
            {
                return NGX_ERROR;
            }

        } else {
            if (!cycle->read_events[s[i].fd].active) {
                continue;
            }

            if (ngx_del_event(&cycle->read_events[s[i].fd], NGX_READ_EVENT,
                                               NGX_DISABLE_EVENT) == NGX_ERROR)
            {
                return NGX_ERROR;
            }
        }
    }

    return NGX_OK;
}


static void
ngx_close_accepted_socket(ngx_socket_t s, ngx_log_t *log)
{
    if (ngx_close_socket(s) == -1) {
        ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
                      ngx_close_socket_n " failed");
    }

#if (NGX_STAT_STUB)
    ngx_atomic_dec(ngx_stat_active);
#endif
}


static u_char *
ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len)
{
    return ngx_snprintf(buf, len, " while accept() on %V", log->data);
}
