|  | 
 | /* | 
 |  * Copyright (C) Igor Sysoev | 
 |  */ | 
 |  | 
 |  | 
 | #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 |