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
nxt_thread_cond_create(nxt_thread_cond_t * cond)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_alert("pthread_cond_init() failed %E", err);
22     return NXT_ERROR;
23 }
24 
25 
26 void
nxt_thread_cond_destroy(nxt_thread_cond_t * cond)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
nxt_thread_cond_signal(nxt_thread_cond_t * cond)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
nxt_thread_cond_wait(nxt_thread_cond_t * cond,nxt_thread_mutex_t * mtx,nxt_nsec_t timeout)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