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