view src/event/ngx_event_posted.c @ 4884:e406c997470a

SSL: the "ssl_verify_client" directive parameter "optional_no_ca". This parameter allows to don't require certificate to be signed by a trusted CA, e.g. if CA certificate isn't known in advance, like in WebID protocol. Note that it doesn't add any security unless the certificate is actually checked to be trusted by some external means (e.g. by a backend). Patch by Mike Kazantsev, Eric O'Connor.
author Maxim Dounin <mdounin@mdounin.ru>
date Wed, 03 Oct 2012 15:24:08 +0000
parents d620f497c50f
children 3377f9459e99
line wrap: on
line source


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


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


ngx_thread_volatile ngx_event_t  *ngx_posted_accept_events;
ngx_thread_volatile ngx_event_t  *ngx_posted_events;

#if (NGX_THREADS)
ngx_mutex_t                      *ngx_posted_events_mutex;
#endif


void
ngx_event_process_posted(ngx_cycle_t *cycle,
    ngx_thread_volatile ngx_event_t **posted)
{
    ngx_event_t  *ev;

    for ( ;; ) {

        ev = (ngx_event_t *) *posted;

        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                      "posted event %p", ev);

        if (ev == NULL) {
            return;
        }

        ngx_delete_posted_event(ev);

        ev->handler(ev);
    }
}


#if (NGX_THREADS) && !(NGX_WIN32)

void
ngx_wakeup_worker_thread(ngx_cycle_t *cycle)
{
    ngx_int_t     i;
#if 0
    ngx_uint_t    busy;
    ngx_event_t  *ev;

    busy = 1;

    if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
        return;
    }

    for (ev = (ngx_event_t *) ngx_posted_events; ev; ev = ev->next) {
        if (*(ev->lock) == 0) {
            busy = 0;
            break;
        }
    }

    ngx_mutex_unlock(ngx_posted_events_mutex);

    if (busy) {
        return;
    }
#endif

    for (i = 0; i < ngx_threads_n; i++) {
        if (ngx_threads[i].state == NGX_THREAD_FREE) {
            ngx_cond_signal(ngx_threads[i].cv);
            return;
        }
    }
}


ngx_int_t
ngx_event_thread_process_posted(ngx_cycle_t *cycle)
{
    ngx_event_t  *ev;

    for ( ;; ) {

        ev = (ngx_event_t *) ngx_posted_events;

        for ( ;; ) {

            ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                          "posted event %p", ev);

            if (ev == NULL) {
                return NGX_OK;
            }

            if (ngx_trylock(ev->lock) == 0) {

                ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                               "posted event %p is busy", ev);

                ev = ev->next;
                continue;
            }

            if (ev->lock != ev->own_lock) {
                if (*(ev->own_lock)) {
                    ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
                             "the own lock of the posted event %p is busy", ev);
                    ngx_unlock(ev->lock);
                    ev = ev->next;
                    continue;
                }
                *(ev->own_lock) = 1;
            }

            ngx_delete_posted_event(ev);

            ev->locked = 1;

            ev->ready |= ev->posted_ready;
            ev->timedout |= ev->posted_timedout;
            ev->pending_eof |= ev->posted_eof;
#if (NGX_HAVE_KQUEUE)
            ev->kq_errno |= ev->posted_errno;
#endif
            if (ev->posted_available) {
                ev->available = ev->posted_available;
            }

            ev->posted_ready = 0;
            ev->posted_timedout = 0;
            ev->posted_eof = 0;
#if (NGX_HAVE_KQUEUE)
            ev->posted_errno = 0;
#endif
            ev->posted_available = 0;

            ngx_mutex_unlock(ngx_posted_events_mutex);

            ev->handler(ev);

            ngx_mutex_lock(ngx_posted_events_mutex);

            if (ev->locked) {
                ngx_unlock(ev->lock);

                if (ev->lock != ev->own_lock) {
                    ngx_unlock(ev->own_lock);
                }
            }

            ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                           "posted event %p is done", ev);

            break;
        }
    }
}

#else

void
ngx_wakeup_worker_thread(ngx_cycle_t *cycle)
{
}

#endif