| /* | |
| * 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 |