1 2 /* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7 #include <nxt_main.h> 8 9 10 nxt_int_t 11 nxt_thread_cond_create(nxt_thread_cond_t *cond) 12 { 13 nxt_err_t err; 14 15 err = pthread_cond_init(cond, NULL); 16 if (err == 0) { 17 nxt_thread_log_debug("pthread_cond_init(%p)", cond); 18 return NXT_OK; 19 } 20 21 nxt_thread_log_emerg("pthread_cond_init() failed %E", err); 22 return NXT_ERROR; 23 } 24 25 26 void 27 nxt_thread_cond_destroy(nxt_thread_cond_t *cond) 28 { 29 nxt_err_t err; 30 31 err = pthread_cond_destroy(cond); 32 if (err != 0) { 33 nxt_thread_log_alert("pthread_cond_destroy() failed %E", err); 34 } 35 36 nxt_thread_log_debug("pthread_cond_destroy(%p)", cond); 37 } 38 39 40 nxt_int_t 41 nxt_thread_cond_signal(nxt_thread_cond_t *cond) 42 { 43 nxt_err_t err; 44 45 err = pthread_cond_signal(cond); 46 if (nxt_fast_path(err == 0)) { 47 nxt_thread_log_debug("pthread_cond_signal(%p)", cond); 48 return NXT_OK; 49 } 50 51 nxt_thread_log_alert("pthread_cond_signal() failed %E", err); 52 53 return NXT_ERROR; 54 } 55 56 57 nxt_err_t 58 nxt_thread_cond_wait(nxt_thread_cond_t *cond, nxt_thread_mutex_t *mtx, 59 nxt_nsec_t timeout) 60 { 61 nxt_err_t err; 62 nxt_nsec_t ns; 63 nxt_thread_t *thr; 64 nxt_realtime_t *now; 65 struct timespec ts; 66 67 thr = nxt_thread(); 68 69 if (timeout == NXT_INFINITE_NSEC) { 70 nxt_log_debug(thr->log, "pthread_cond_wait(%p) enter", cond); 71 72 err = pthread_cond_wait(cond, mtx); 73 74 nxt_thread_time_update(thr); 75 76 if (nxt_fast_path(err == 0)) { 77 nxt_log_debug(thr->log, "pthread_cond_wait(%p) exit", cond); 78 return 0; 79 } 80 81 nxt_log_alert(thr->log, "pthread_cond_wait() failed %E", err); 82 83 } else { 84 nxt_log_debug(thr->log, "pthread_cond_timedwait(%p, %N) enter", 85 cond, timeout); 86 87 now = nxt_thread_realtime(thr); 88 89 ns = now->nsec + timeout; 90 ts.tv_sec = now->sec + ns / 1000000000; 91 ts.tv_nsec = ns % 1000000000; 92 93 err = pthread_cond_timedwait(cond, mtx, &ts); 94 95 nxt_thread_time_update(thr); 96 97 if (nxt_fast_path(err == 0 || err == NXT_ETIMEDOUT)) { 98 nxt_log_debug(thr->log, "pthread_cond_timedwait(%p) exit: %d", 99 cond, err); 100 return err; 101 } 102 103 nxt_log_alert(thr->log, "pthread_cond_timedwait() failed %E", err); 104 } 105 106 return NXT_ERROR; 107 } 108