10Sigor@sysoev.ru 20Sigor@sysoev.ru /* 30Sigor@sysoev.ru * Copyright (C) Igor Sysoev 40Sigor@sysoev.ru * Copyright (C) NGINX, Inc. 50Sigor@sysoev.ru */ 60Sigor@sysoev.ru 70Sigor@sysoev.ru #include <nxt_main.h> 80Sigor@sysoev.ru 90Sigor@sysoev.ru 100Sigor@sysoev.ru nxt_int_t 110Sigor@sysoev.ru nxt_thread_cond_create(nxt_thread_cond_t *cond) 120Sigor@sysoev.ru { 130Sigor@sysoev.ru nxt_err_t err; 140Sigor@sysoev.ru 150Sigor@sysoev.ru err = pthread_cond_init(cond, NULL); 160Sigor@sysoev.ru if (err == 0) { 170Sigor@sysoev.ru nxt_thread_log_debug("pthread_cond_init(%p)", cond); 180Sigor@sysoev.ru return NXT_OK; 190Sigor@sysoev.ru } 200Sigor@sysoev.ru 21*564Svbart@nginx.com nxt_thread_log_alert("pthread_cond_init() failed %E", err); 220Sigor@sysoev.ru return NXT_ERROR; 230Sigor@sysoev.ru } 240Sigor@sysoev.ru 250Sigor@sysoev.ru 260Sigor@sysoev.ru void 270Sigor@sysoev.ru nxt_thread_cond_destroy(nxt_thread_cond_t *cond) 280Sigor@sysoev.ru { 290Sigor@sysoev.ru nxt_err_t err; 300Sigor@sysoev.ru 310Sigor@sysoev.ru err = pthread_cond_destroy(cond); 320Sigor@sysoev.ru if (err != 0) { 330Sigor@sysoev.ru nxt_thread_log_alert("pthread_cond_destroy() failed %E", err); 340Sigor@sysoev.ru } 350Sigor@sysoev.ru 360Sigor@sysoev.ru nxt_thread_log_debug("pthread_cond_destroy(%p)", cond); 370Sigor@sysoev.ru } 380Sigor@sysoev.ru 390Sigor@sysoev.ru 400Sigor@sysoev.ru nxt_int_t 410Sigor@sysoev.ru nxt_thread_cond_signal(nxt_thread_cond_t *cond) 420Sigor@sysoev.ru { 430Sigor@sysoev.ru nxt_err_t err; 440Sigor@sysoev.ru 450Sigor@sysoev.ru err = pthread_cond_signal(cond); 460Sigor@sysoev.ru if (nxt_fast_path(err == 0)) { 470Sigor@sysoev.ru nxt_thread_log_debug("pthread_cond_signal(%p)", cond); 480Sigor@sysoev.ru return NXT_OK; 490Sigor@sysoev.ru } 500Sigor@sysoev.ru 510Sigor@sysoev.ru nxt_thread_log_alert("pthread_cond_signal() failed %E", err); 520Sigor@sysoev.ru 530Sigor@sysoev.ru return NXT_ERROR; 540Sigor@sysoev.ru } 550Sigor@sysoev.ru 560Sigor@sysoev.ru 570Sigor@sysoev.ru nxt_err_t 580Sigor@sysoev.ru nxt_thread_cond_wait(nxt_thread_cond_t *cond, nxt_thread_mutex_t *mtx, 590Sigor@sysoev.ru nxt_nsec_t timeout) 600Sigor@sysoev.ru { 610Sigor@sysoev.ru nxt_err_t err; 620Sigor@sysoev.ru nxt_nsec_t ns; 630Sigor@sysoev.ru nxt_thread_t *thr; 640Sigor@sysoev.ru nxt_realtime_t *now; 650Sigor@sysoev.ru struct timespec ts; 660Sigor@sysoev.ru 670Sigor@sysoev.ru thr = nxt_thread(); 680Sigor@sysoev.ru 690Sigor@sysoev.ru if (timeout == NXT_INFINITE_NSEC) { 700Sigor@sysoev.ru nxt_log_debug(thr->log, "pthread_cond_wait(%p) enter", cond); 710Sigor@sysoev.ru 720Sigor@sysoev.ru err = pthread_cond_wait(cond, mtx); 730Sigor@sysoev.ru 740Sigor@sysoev.ru nxt_thread_time_update(thr); 750Sigor@sysoev.ru 760Sigor@sysoev.ru if (nxt_fast_path(err == 0)) { 770Sigor@sysoev.ru nxt_log_debug(thr->log, "pthread_cond_wait(%p) exit", cond); 780Sigor@sysoev.ru return 0; 790Sigor@sysoev.ru } 800Sigor@sysoev.ru 810Sigor@sysoev.ru nxt_log_alert(thr->log, "pthread_cond_wait() failed %E", err); 820Sigor@sysoev.ru 830Sigor@sysoev.ru } else { 840Sigor@sysoev.ru nxt_log_debug(thr->log, "pthread_cond_timedwait(%p, %N) enter", 850Sigor@sysoev.ru cond, timeout); 860Sigor@sysoev.ru 870Sigor@sysoev.ru now = nxt_thread_realtime(thr); 880Sigor@sysoev.ru 890Sigor@sysoev.ru ns = now->nsec + timeout; 900Sigor@sysoev.ru ts.tv_sec = now->sec + ns / 1000000000; 910Sigor@sysoev.ru ts.tv_nsec = ns % 1000000000; 920Sigor@sysoev.ru 930Sigor@sysoev.ru err = pthread_cond_timedwait(cond, mtx, &ts); 940Sigor@sysoev.ru 950Sigor@sysoev.ru nxt_thread_time_update(thr); 960Sigor@sysoev.ru 970Sigor@sysoev.ru if (nxt_fast_path(err == 0 || err == NXT_ETIMEDOUT)) { 980Sigor@sysoev.ru nxt_log_debug(thr->log, "pthread_cond_timedwait(%p) exit: %d", 990Sigor@sysoev.ru cond, err); 1000Sigor@sysoev.ru return err; 1010Sigor@sysoev.ru } 1020Sigor@sysoev.ru 1030Sigor@sysoev.ru nxt_log_alert(thr->log, "pthread_cond_timedwait() failed %E", err); 1040Sigor@sysoev.ru } 1050Sigor@sysoev.ru 1060Sigor@sysoev.ru return NXT_ERROR; 1070Sigor@sysoev.ru } 108