Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ngx_pthread_thread.c
Go to the documentation of this file.
1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) Nginx, Inc.
5  */
6 
7 
8 #include <ngx_config.h>
9 #include <ngx_core.h>
10 
11 
12 static ngx_uint_t nthreads;
13 static ngx_uint_t max_threads;
14 
15 
16 static pthread_attr_t thr_attr;
17 
18 
20 ngx_create_thread(ngx_tid_t *tid, ngx_thread_value_t (*func)(void *arg),
21  void *arg, ngx_log_t *log)
22 {
23  int err;
24 
25  if (nthreads >= max_threads) {
27  "no more than %ui threads can be created", max_threads);
28  return NGX_ERROR;
29  }
30 
31  err = pthread_create(tid, &thr_attr, func, arg);
32 
33  if (err != 0) {
34  ngx_log_error(NGX_LOG_ALERT, log, err, "pthread_create() failed");
35  return err;
36  }
37 
39  "thread is created: " NGX_TID_T_FMT, *tid);
40 
41  nthreads++;
42 
43  return err;
44 }
45 
46 
48 ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle)
49 {
50  int err;
51 
52  max_threads = n;
53 
54  err = pthread_attr_init(&thr_attr);
55 
56  if (err != 0) {
57  ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
58  "pthread_attr_init() failed");
59  return NGX_ERROR;
60  }
61 
62  err = pthread_attr_setstacksize(&thr_attr, size);
63 
64  if (err != 0) {
65  ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
66  "pthread_attr_setstacksize() failed");
67  return NGX_ERROR;
68  }
69 
70  ngx_threaded = 1;
71 
72  return NGX_OK;
73 }
74 
75 
78 {
79  int err;
80  ngx_mutex_t *m;
81 
82  m = ngx_alloc(sizeof(ngx_mutex_t), log);
83  if (m == NULL) {
84  return NULL;
85  }
86 
87  m->log = log;
88 
89  err = pthread_mutex_init(&m->mutex, NULL);
90 
91  if (err != 0) {
93  "pthread_mutex_init() failed");
94  return NULL;
95  }
96 
97  return m;
98 }
99 
100 
101 void
103 {
104  int err;
105 
106  err = pthread_mutex_destroy(&m->mutex);
107 
108  if (err != 0) {
110  "pthread_mutex_destroy(%p) failed", m);
111  }
112 
113  ngx_free(m);
114 }
115 
116 
117 void
119 {
120  int err;
121 
122  if (!ngx_threaded) {
123  return;
124  }
125 
126  ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "lock mutex %p", m);
127 
128  err = pthread_mutex_lock(&m->mutex);
129 
130  if (err != 0) {
132  "pthread_mutex_lock(%p) failed", m);
133  ngx_abort();
134  }
135 
136  ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is locked", m);
137 
138  return;
139 }
140 
141 
142 ngx_int_t
144 {
145  int err;
146 
147  if (!ngx_threaded) {
148  return NGX_OK;
149  }
150 
151  ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "try lock mutex %p", m);
152 
153  err = pthread_mutex_trylock(&m->mutex);
154 
155  if (err == NGX_EBUSY) {
156  return NGX_AGAIN;
157  }
158 
159  if (err != 0) {
161  "pthread_mutex_trylock(%p) failed", m);
162  ngx_abort();
163  }
164 
165  ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is locked", m);
166 
167  return NGX_OK;
168 }
169 
170 
171 void
173 {
174  int err;
175 
176  if (!ngx_threaded) {
177  return;
178  }
179 
180  ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "unlock mutex %p", m);
181 
182  err = pthread_mutex_unlock(&m->mutex);
183 
184  if (err != 0) {
186  "pthread_mutex_unlock(%p) failed", m);
187  ngx_abort();
188  }
189 
190  ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is unlocked", m);
191 
192  return;
193 }
194 
195 
196 ngx_cond_t *
198 {
199  int err;
200  ngx_cond_t *cv;
201 
202  cv = ngx_alloc(sizeof(ngx_cond_t), log);
203  if (cv == NULL) {
204  return NULL;
205  }
206 
207  cv->log = log;
208 
209  err = pthread_cond_init(&cv->cond, NULL);
210 
211  if (err != 0) {
212  ngx_log_error(NGX_LOG_ALERT, cv->log, err,
213  "pthread_cond_init() failed");
214  return NULL;
215  }
216 
217  return cv;
218 }
219 
220 
221 void
223 {
224  int err;
225 
226  err = pthread_cond_destroy(&cv->cond);
227 
228  if (err != 0) {
229  ngx_log_error(NGX_LOG_ALERT, cv->log, err,
230  "pthread_cond_destroy(%p) failed", cv);
231  }
232 
233  ngx_free(cv);
234 }
235 
236 
237 ngx_int_t
239 {
240  int err;
241 
242  ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p wait", cv);
243 
244  err = pthread_cond_wait(&cv->cond, &m->mutex);
245 
246  if (err != 0) {
247  ngx_log_error(NGX_LOG_ALERT, cv->log, err,
248  "pthread_cond_wait(%p) failed", cv);
249  return NGX_ERROR;
250  }
251 
252  ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p is waked up", cv);
253 
254  ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is locked", m);
255 
256  return NGX_OK;
257 }
258 
259 
260 ngx_int_t
262 {
263  int err;
264 
265  ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p to signal", cv);
266 
267  err = pthread_cond_signal(&cv->cond);
268 
269  if (err != 0) {
270  ngx_log_error(NGX_LOG_ALERT, cv->log, err,
271  "pthread_cond_signal(%p) failed", cv);
272  return NGX_ERROR;
273  }
274 
275  ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p is signaled", cv);
276 
277  return NGX_OK;
278 }