nginxtra 1.6.3.9 → 1.8.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. checksums.yaml +4 -4
  2. data/bin/nginxtra +1 -1
  3. data/bin/nginxtra_rails +1 -1
  4. data/lib/nginxtra/version.rb +1 -1
  5. data/vendor/nginx/CHANGES +358 -14
  6. data/vendor/nginx/CHANGES.ru +372 -18
  7. data/vendor/nginx/LICENSE +2 -2
  8. data/vendor/nginx/auto/cc/clang +5 -0
  9. data/vendor/nginx/auto/cc/gcc +5 -0
  10. data/vendor/nginx/auto/lib/google-perftools/conf +1 -1
  11. data/vendor/nginx/auto/lib/openssl/make +0 -5
  12. data/vendor/nginx/auto/lib/perl/conf +9 -1
  13. data/vendor/nginx/auto/make +1 -1
  14. data/vendor/nginx/auto/modules +11 -0
  15. data/vendor/nginx/auto/options +10 -2
  16. data/vendor/nginx/auto/os/darwin +0 -1
  17. data/vendor/nginx/auto/os/freebsd +6 -23
  18. data/vendor/nginx/auto/sources +16 -14
  19. data/vendor/nginx/auto/summary +3 -24
  20. data/vendor/nginx/auto/threads +20 -0
  21. data/vendor/nginx/auto/types/sizeof +2 -12
  22. data/vendor/nginx/auto/unix +50 -6
  23. data/vendor/nginx/configure +5 -0
  24. data/vendor/nginx/contrib/vim/syntax/nginx.vim +183 -50
  25. data/vendor/nginx/src/core/nginx.c +21 -9
  26. data/vendor/nginx/src/core/nginx.h +8 -2
  27. data/vendor/nginx/src/core/ngx_buf.c +88 -0
  28. data/vendor/nginx/src/core/ngx_buf.h +15 -1
  29. data/vendor/nginx/src/core/ngx_conf_file.c +4 -1
  30. data/vendor/nginx/src/core/ngx_connection.c +25 -66
  31. data/vendor/nginx/src/core/ngx_connection.h +1 -3
  32. data/vendor/nginx/src/core/ngx_core.h +11 -3
  33. data/vendor/nginx/src/core/ngx_crypt.c +1 -1
  34. data/vendor/nginx/src/core/ngx_cycle.c +7 -1
  35. data/vendor/nginx/src/core/ngx_cycle.h +6 -2
  36. data/vendor/nginx/src/core/ngx_file.c +13 -5
  37. data/vendor/nginx/src/core/ngx_file.h +6 -0
  38. data/vendor/nginx/src/core/ngx_log.c +215 -21
  39. data/vendor/nginx/src/core/ngx_log.h +9 -1
  40. data/vendor/nginx/src/core/ngx_output_chain.c +104 -15
  41. data/vendor/nginx/src/core/ngx_palloc.c +3 -7
  42. data/vendor/nginx/src/core/ngx_rbtree.c +2 -4
  43. data/vendor/nginx/src/core/ngx_rbtree.h +2 -4
  44. data/vendor/nginx/src/core/ngx_regex.c +14 -6
  45. data/vendor/nginx/src/core/ngx_resolver.c +16 -23
  46. data/vendor/nginx/src/core/ngx_resolver.h +8 -7
  47. data/vendor/nginx/src/core/ngx_shmtx.c +1 -1
  48. data/vendor/nginx/src/core/ngx_slab.c +89 -2
  49. data/vendor/nginx/src/core/ngx_slab.h +3 -0
  50. data/vendor/nginx/src/core/ngx_string.c +58 -2
  51. data/vendor/nginx/src/core/ngx_string.h +1 -0
  52. data/vendor/nginx/src/core/ngx_syslog.c +374 -0
  53. data/vendor/nginx/src/core/ngx_syslog.h +30 -0
  54. data/vendor/nginx/src/core/ngx_thread_pool.c +630 -0
  55. data/vendor/nginx/src/core/ngx_thread_pool.h +36 -0
  56. data/vendor/nginx/src/core/ngx_times.c +19 -2
  57. data/vendor/nginx/src/core/ngx_times.h +1 -0
  58. data/vendor/nginx/src/event/modules/ngx_aio_module.c +1 -1
  59. data/vendor/nginx/src/event/modules/ngx_devpoll_module.c +9 -24
  60. data/vendor/nginx/src/event/modules/ngx_epoll_module.c +152 -28
  61. data/vendor/nginx/src/event/modules/ngx_eventport_module.c +43 -25
  62. data/vendor/nginx/src/event/modules/ngx_kqueue_module.c +86 -156
  63. data/vendor/nginx/src/event/modules/ngx_poll_module.c +21 -37
  64. data/vendor/nginx/src/event/modules/ngx_rtsig_module.c +15 -27
  65. data/vendor/nginx/src/event/modules/ngx_select_module.c +10 -12
  66. data/vendor/nginx/src/event/modules/ngx_win32_select_module.c +7 -9
  67. data/vendor/nginx/src/event/ngx_event.c +5 -33
  68. data/vendor/nginx/src/event/ngx_event.h +15 -50
  69. data/vendor/nginx/src/event/ngx_event_accept.c +11 -10
  70. data/vendor/nginx/src/event/ngx_event_connect.c +0 -11
  71. data/vendor/nginx/src/event/ngx_event_connect.h +1 -4
  72. data/vendor/nginx/src/event/ngx_event_openssl.c +622 -38
  73. data/vendor/nginx/src/event/ngx_event_openssl.h +20 -2
  74. data/vendor/nginx/src/event/ngx_event_openssl_stapling.c +5 -1
  75. data/vendor/nginx/src/event/ngx_event_pipe.c +45 -19
  76. data/vendor/nginx/src/event/ngx_event_pipe.h +3 -0
  77. data/vendor/nginx/src/event/ngx_event_posted.c +7 -145
  78. data/vendor/nginx/src/event/ngx_event_posted.h +12 -39
  79. data/vendor/nginx/src/event/ngx_event_timer.c +50 -70
  80. data/vendor/nginx/src/event/ngx_event_timer.h +2 -14
  81. data/vendor/nginx/src/http/modules/ngx_http_addition_filter_module.c +1 -1
  82. data/vendor/nginx/src/http/modules/ngx_http_autoindex_module.c +416 -71
  83. data/vendor/nginx/src/http/modules/ngx_http_charset_filter_module.c +19 -15
  84. data/vendor/nginx/src/http/modules/ngx_http_dav_module.c +16 -4
  85. data/vendor/nginx/src/http/modules/ngx_http_fastcgi_module.c +601 -134
  86. data/vendor/nginx/src/http/modules/ngx_http_geo_module.c +1 -1
  87. data/vendor/nginx/src/http/modules/ngx_http_geoip_module.c +9 -3
  88. data/vendor/nginx/src/http/modules/ngx_http_gunzip_filter_module.c +9 -3
  89. data/vendor/nginx/src/http/modules/ngx_http_gzip_filter_module.c +9 -3
  90. data/vendor/nginx/src/http/modules/ngx_http_gzip_static_module.c +0 -2
  91. data/vendor/nginx/src/http/modules/ngx_http_headers_filter_module.c +197 -91
  92. data/vendor/nginx/src/http/modules/ngx_http_image_filter_module.c +1 -0
  93. data/vendor/nginx/src/http/modules/ngx_http_limit_conn_module.c +65 -162
  94. data/vendor/nginx/src/http/modules/ngx_http_limit_req_module.c +53 -67
  95. data/vendor/nginx/src/http/modules/ngx_http_log_module.c +128 -23
  96. data/vendor/nginx/src/http/modules/ngx_http_memcached_module.c +25 -6
  97. data/vendor/nginx/src/http/modules/ngx_http_mp4_module.c +1 -1
  98. data/vendor/nginx/src/http/modules/ngx_http_not_modified_filter_module.c +39 -13
  99. data/vendor/nginx/src/http/modules/ngx_http_proxy_module.c +697 -141
  100. data/vendor/nginx/src/http/modules/ngx_http_rewrite_module.c +5 -1
  101. data/vendor/nginx/src/http/modules/ngx_http_scgi_module.c +282 -125
  102. data/vendor/nginx/src/http/modules/ngx_http_ssi_filter_module.c +4 -1
  103. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.c +44 -1
  104. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.h +2 -0
  105. data/vendor/nginx/src/http/modules/ngx_http_stub_status_module.c +10 -8
  106. data/vendor/nginx/src/http/modules/ngx_http_sub_filter_module.c +18 -3
  107. data/vendor/nginx/src/http/modules/ngx_http_upstream_hash_module.c +641 -0
  108. data/vendor/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +1 -1
  109. data/vendor/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c +3 -21
  110. data/vendor/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c +0 -5
  111. data/vendor/nginx/src/http/modules/ngx_http_uwsgi_module.c +449 -125
  112. data/vendor/nginx/src/http/modules/ngx_http_xslt_filter_module.c +4 -2
  113. data/vendor/nginx/src/http/modules/perl/ngx_http_perl_module.c +2 -1
  114. data/vendor/nginx/src/http/ngx_http.c +10 -5
  115. data/vendor/nginx/src/http/ngx_http.h +4 -4
  116. data/vendor/nginx/src/http/ngx_http_cache.h +26 -1
  117. data/vendor/nginx/src/http/ngx_http_copy_filter_module.c +109 -68
  118. data/vendor/nginx/src/http/ngx_http_core_module.c +191 -46
  119. data/vendor/nginx/src/http/ngx_http_core_module.h +16 -4
  120. data/vendor/nginx/src/http/ngx_http_file_cache.c +584 -67
  121. data/vendor/nginx/src/http/ngx_http_parse.c +55 -4
  122. data/vendor/nginx/src/http/ngx_http_request.c +14 -6
  123. data/vendor/nginx/src/http/ngx_http_request.h +12 -4
  124. data/vendor/nginx/src/http/ngx_http_request_body.c +114 -28
  125. data/vendor/nginx/src/http/ngx_http_spdy.c +383 -229
  126. data/vendor/nginx/src/http/ngx_http_spdy.h +8 -5
  127. data/vendor/nginx/src/http/ngx_http_spdy_filter_module.c +12 -4
  128. data/vendor/nginx/src/http/ngx_http_special_response.c +2 -2
  129. data/vendor/nginx/src/http/ngx_http_upstream.c +808 -132
  130. data/vendor/nginx/src/http/ngx_http_upstream.h +33 -3
  131. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.c +72 -65
  132. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.h +1 -2
  133. data/vendor/nginx/src/http/ngx_http_variables.c +47 -3
  134. data/vendor/nginx/src/http/ngx_http_write_filter_module.c +15 -6
  135. data/vendor/nginx/src/mail/ngx_mail.c +2 -3
  136. data/vendor/nginx/src/mail/ngx_mail.h +2 -0
  137. data/vendor/nginx/src/mail/ngx_mail_auth_http_module.c +140 -11
  138. data/vendor/nginx/src/mail/ngx_mail_core_module.c +3 -3
  139. data/vendor/nginx/src/mail/ngx_mail_handler.c +79 -2
  140. data/vendor/nginx/src/mail/ngx_mail_imap_module.c +3 -1
  141. data/vendor/nginx/src/mail/ngx_mail_pop3_module.c +3 -1
  142. data/vendor/nginx/src/mail/ngx_mail_smtp_module.c +3 -1
  143. data/vendor/nginx/src/mail/ngx_mail_ssl_module.c +125 -1
  144. data/vendor/nginx/src/mail/ngx_mail_ssl_module.h +8 -0
  145. data/vendor/nginx/src/misc/ngx_cpp_test_module.cpp +1 -1
  146. data/vendor/nginx/src/os/unix/ngx_aio_read_chain.c +1 -1
  147. data/vendor/nginx/src/os/unix/ngx_channel.c +0 -7
  148. data/vendor/nginx/src/os/unix/ngx_darwin_config.h +0 -3
  149. data/vendor/nginx/src/os/unix/ngx_darwin_sendfile_chain.c +44 -208
  150. data/vendor/nginx/src/os/unix/ngx_file_aio_read.c +25 -17
  151. data/vendor/nginx/src/os/unix/ngx_files.c +109 -0
  152. data/vendor/nginx/src/os/unix/ngx_files.h +6 -0
  153. data/vendor/nginx/src/os/unix/ngx_freebsd_config.h +0 -6
  154. data/vendor/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c +78 -206
  155. data/vendor/nginx/src/os/unix/ngx_linux_aio_read.c +25 -14
  156. data/vendor/nginx/src/os/unix/ngx_linux_config.h +4 -1
  157. data/vendor/nginx/src/os/unix/ngx_linux_sendfile_chain.c +235 -194
  158. data/vendor/nginx/src/os/unix/ngx_os.h +25 -3
  159. data/vendor/nginx/src/os/unix/ngx_posix_init.c +4 -2
  160. data/vendor/nginx/src/os/unix/ngx_process_cycle.c +13 -195
  161. data/vendor/nginx/src/os/unix/ngx_process_cycle.h +0 -1
  162. data/vendor/nginx/src/os/unix/ngx_readv_chain.c +27 -108
  163. data/vendor/nginx/src/os/unix/ngx_setproctitle.h +2 -2
  164. data/vendor/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c +12 -67
  165. data/vendor/nginx/src/os/unix/ngx_thread.h +26 -83
  166. data/vendor/nginx/src/os/unix/ngx_thread_cond.c +87 -0
  167. data/vendor/nginx/src/os/unix/ngx_thread_id.c +70 -0
  168. data/vendor/nginx/src/os/unix/ngx_thread_mutex.c +174 -0
  169. data/vendor/nginx/src/os/unix/ngx_user.c +2 -20
  170. data/vendor/nginx/src/os/unix/ngx_writev_chain.c +129 -98
  171. metadata +16 -17
  172. data/vendor/nginx/auto/lib/zlib/patch.zlib.h +0 -10
  173. data/vendor/nginx/src/event/ngx_event_busy_lock.c +0 -286
  174. data/vendor/nginx/src/event/ngx_event_busy_lock.h +0 -65
  175. data/vendor/nginx/src/event/ngx_event_mutex.c +0 -70
  176. data/vendor/nginx/src/http/ngx_http_busy_lock.c +0 -307
  177. data/vendor/nginx/src/http/ngx_http_busy_lock.h +0 -54
  178. data/vendor/nginx/src/os/unix/ngx_freebsd_rfork_thread.c +0 -756
  179. data/vendor/nginx/src/os/unix/ngx_freebsd_rfork_thread.h +0 -122
  180. data/vendor/nginx/src/os/unix/ngx_pthread_thread.c +0 -278
  181. data/vendor/nginx/src/os/unix/rfork_thread.S +0 -73
@@ -0,0 +1,30 @@
1
+
2
+ /*
3
+ * Copyright (C) Nginx, Inc.
4
+ */
5
+
6
+
7
+ #ifndef _NGX_SYSLOG_H_INCLUDED_
8
+ #define _NGX_SYSLOG_H_INCLUDED_
9
+
10
+
11
+ typedef struct {
12
+ ngx_pool_t *pool;
13
+ ngx_uint_t facility;
14
+ ngx_uint_t severity;
15
+ ngx_str_t tag;
16
+
17
+ ngx_addr_t server;
18
+ ngx_connection_t conn;
19
+ ngx_uint_t busy; /* unsigned busy:1; */
20
+ } ngx_syslog_peer_t;
21
+
22
+
23
+ char *ngx_syslog_process_conf(ngx_conf_t *cf, ngx_syslog_peer_t *peer);
24
+ u_char *ngx_syslog_add_header(ngx_syslog_peer_t *peer, u_char *buf);
25
+ void ngx_syslog_writer(ngx_log_t *log, ngx_uint_t level, u_char *buf,
26
+ size_t len);
27
+ ssize_t ngx_syslog_send(ngx_syslog_peer_t *peer, u_char *buf, size_t len);
28
+
29
+
30
+ #endif /* _NGX_SYSLOG_H_INCLUDED_ */
@@ -0,0 +1,630 @@
1
+
2
+ /*
3
+ * Copyright (C) Nginx, Inc.
4
+ * Copyright (C) Valentin V. Bartenev
5
+ * Copyright (C) Ruslan Ermilov
6
+ */
7
+
8
+
9
+ #include <ngx_config.h>
10
+ #include <ngx_core.h>
11
+ #include <ngx_thread_pool.h>
12
+
13
+
14
+ typedef struct {
15
+ ngx_array_t pools;
16
+ } ngx_thread_pool_conf_t;
17
+
18
+
19
+ typedef struct {
20
+ ngx_thread_task_t *first;
21
+ ngx_thread_task_t **last;
22
+ } ngx_thread_pool_queue_t;
23
+
24
+ #define ngx_thread_pool_queue_init(q) \
25
+ (q)->first = NULL; \
26
+ (q)->last = &(q)->first
27
+
28
+
29
+ struct ngx_thread_pool_s {
30
+ ngx_thread_mutex_t mtx;
31
+ ngx_thread_pool_queue_t queue;
32
+ ngx_int_t waiting;
33
+ ngx_thread_cond_t cond;
34
+
35
+ ngx_log_t *log;
36
+
37
+ ngx_str_t name;
38
+ ngx_uint_t threads;
39
+ ngx_int_t max_queue;
40
+
41
+ u_char *file;
42
+ ngx_uint_t line;
43
+ };
44
+
45
+
46
+ static ngx_int_t ngx_thread_pool_init(ngx_thread_pool_t *tp, ngx_log_t *log,
47
+ ngx_pool_t *pool);
48
+ static void ngx_thread_pool_destroy(ngx_thread_pool_t *tp);
49
+ static void ngx_thread_pool_exit_handler(void *data, ngx_log_t *log);
50
+
51
+ static void *ngx_thread_pool_cycle(void *data);
52
+ static void ngx_thread_pool_handler(ngx_event_t *ev);
53
+
54
+ static char *ngx_thread_pool(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
55
+
56
+ static void *ngx_thread_pool_create_conf(ngx_cycle_t *cycle);
57
+ static char *ngx_thread_pool_init_conf(ngx_cycle_t *cycle, void *conf);
58
+
59
+ static ngx_int_t ngx_thread_pool_init_worker(ngx_cycle_t *cycle);
60
+ static void ngx_thread_pool_exit_worker(ngx_cycle_t *cycle);
61
+
62
+
63
+ static ngx_command_t ngx_thread_pool_commands[] = {
64
+
65
+ { ngx_string("thread_pool"),
66
+ NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE23,
67
+ ngx_thread_pool,
68
+ 0,
69
+ 0,
70
+ NULL },
71
+
72
+ ngx_null_command
73
+ };
74
+
75
+
76
+ static ngx_core_module_t ngx_thread_pool_module_ctx = {
77
+ ngx_string("thread_pool"),
78
+ ngx_thread_pool_create_conf,
79
+ ngx_thread_pool_init_conf
80
+ };
81
+
82
+
83
+ ngx_module_t ngx_thread_pool_module = {
84
+ NGX_MODULE_V1,
85
+ &ngx_thread_pool_module_ctx, /* module context */
86
+ ngx_thread_pool_commands, /* module directives */
87
+ NGX_CORE_MODULE, /* module type */
88
+ NULL, /* init master */
89
+ NULL, /* init module */
90
+ ngx_thread_pool_init_worker, /* init process */
91
+ NULL, /* init thread */
92
+ NULL, /* exit thread */
93
+ ngx_thread_pool_exit_worker, /* exit process */
94
+ NULL, /* exit master */
95
+ NGX_MODULE_V1_PADDING
96
+ };
97
+
98
+
99
+ static ngx_str_t ngx_thread_pool_default = ngx_string("default");
100
+
101
+ static ngx_uint_t ngx_thread_pool_task_id;
102
+ static ngx_atomic_t ngx_thread_pool_done_lock;
103
+ static ngx_thread_pool_queue_t ngx_thread_pool_done;
104
+
105
+
106
+ static ngx_int_t
107
+ ngx_thread_pool_init(ngx_thread_pool_t *tp, ngx_log_t *log, ngx_pool_t *pool)
108
+ {
109
+ int err;
110
+ pthread_t tid;
111
+ ngx_uint_t n;
112
+ pthread_attr_t attr;
113
+
114
+ if (ngx_notify == NULL) {
115
+ ngx_log_error(NGX_LOG_ALERT, log, 0,
116
+ "the configured event method cannot be used with thread pools");
117
+ return NGX_ERROR;
118
+ }
119
+
120
+ ngx_thread_pool_queue_init(&tp->queue);
121
+
122
+ if (ngx_thread_mutex_create(&tp->mtx, log) != NGX_OK) {
123
+ return NGX_ERROR;
124
+ }
125
+
126
+ if (ngx_thread_cond_create(&tp->cond, log) != NGX_OK) {
127
+ (void) ngx_thread_mutex_destroy(&tp->mtx, log);
128
+ return NGX_ERROR;
129
+ }
130
+
131
+ tp->log = log;
132
+
133
+ err = pthread_attr_init(&attr);
134
+ if (err) {
135
+ ngx_log_error(NGX_LOG_ALERT, log, err,
136
+ "pthread_attr_init() failed");
137
+ return NGX_ERROR;
138
+ }
139
+
140
+ #if 0
141
+ err = pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN);
142
+ if (err) {
143
+ ngx_log_error(NGX_LOG_ALERT, log, err,
144
+ "pthread_attr_setstacksize() failed");
145
+ return NGX_ERROR;
146
+ }
147
+ #endif
148
+
149
+ for (n = 0; n < tp->threads; n++) {
150
+ err = pthread_create(&tid, &attr, ngx_thread_pool_cycle, tp);
151
+ if (err) {
152
+ ngx_log_error(NGX_LOG_ALERT, log, err,
153
+ "pthread_create() failed");
154
+ return NGX_ERROR;
155
+ }
156
+ }
157
+
158
+ (void) pthread_attr_destroy(&attr);
159
+
160
+ return NGX_OK;
161
+ }
162
+
163
+
164
+ static void
165
+ ngx_thread_pool_destroy(ngx_thread_pool_t *tp)
166
+ {
167
+ ngx_uint_t n;
168
+ ngx_thread_task_t task;
169
+ volatile ngx_uint_t lock;
170
+
171
+ ngx_memzero(&task, sizeof(ngx_thread_task_t));
172
+
173
+ task.handler = ngx_thread_pool_exit_handler;
174
+ task.ctx = (void *) &lock;
175
+
176
+ for (n = 0; n < tp->threads; n++) {
177
+ lock = 1;
178
+
179
+ if (ngx_thread_task_post(tp, &task) != NGX_OK) {
180
+ return;
181
+ }
182
+
183
+ while (lock) {
184
+ ngx_sched_yield();
185
+ }
186
+
187
+ task.event.active = 0;
188
+ }
189
+
190
+ (void) ngx_thread_cond_destroy(&tp->cond, tp->log);
191
+
192
+ (void) ngx_thread_mutex_destroy(&tp->mtx, tp->log);
193
+ }
194
+
195
+
196
+ static void
197
+ ngx_thread_pool_exit_handler(void *data, ngx_log_t *log)
198
+ {
199
+ ngx_uint_t *lock = data;
200
+
201
+ *lock = 0;
202
+
203
+ pthread_exit(0);
204
+ }
205
+
206
+
207
+ ngx_thread_task_t *
208
+ ngx_thread_task_alloc(ngx_pool_t *pool, size_t size)
209
+ {
210
+ ngx_thread_task_t *task;
211
+
212
+ task = ngx_pcalloc(pool, sizeof(ngx_thread_task_t) + size);
213
+ if (task == NULL) {
214
+ return NULL;
215
+ }
216
+
217
+ task->ctx = task + 1;
218
+
219
+ return task;
220
+ }
221
+
222
+
223
+ ngx_int_t
224
+ ngx_thread_task_post(ngx_thread_pool_t *tp, ngx_thread_task_t *task)
225
+ {
226
+ if (task->event.active) {
227
+ ngx_log_error(NGX_LOG_ALERT, tp->log, 0,
228
+ "task #%ui already active", task->id);
229
+ return NGX_ERROR;
230
+ }
231
+
232
+ if (ngx_thread_mutex_lock(&tp->mtx, tp->log) != NGX_OK) {
233
+ return NGX_ERROR;
234
+ }
235
+
236
+ if (tp->waiting >= tp->max_queue) {
237
+ (void) ngx_thread_mutex_unlock(&tp->mtx, tp->log);
238
+
239
+ ngx_log_error(NGX_LOG_ERR, tp->log, 0,
240
+ "thread pool \"%V\" queue overflow: %i tasks waiting",
241
+ &tp->name, tp->waiting);
242
+ return NGX_ERROR;
243
+ }
244
+
245
+ task->event.active = 1;
246
+
247
+ task->id = ngx_thread_pool_task_id++;
248
+ task->next = NULL;
249
+
250
+ if (ngx_thread_cond_signal(&tp->cond, tp->log) != NGX_OK) {
251
+ (void) ngx_thread_mutex_unlock(&tp->mtx, tp->log);
252
+ return NGX_ERROR;
253
+ }
254
+
255
+ *tp->queue.last = task;
256
+ tp->queue.last = &task->next;
257
+
258
+ tp->waiting++;
259
+
260
+ (void) ngx_thread_mutex_unlock(&tp->mtx, tp->log);
261
+
262
+ ngx_log_debug2(NGX_LOG_DEBUG_CORE, tp->log, 0,
263
+ "task #%ui added to thread pool \"%V\"",
264
+ task->id, &tp->name);
265
+
266
+ return NGX_OK;
267
+ }
268
+
269
+
270
+ static void *
271
+ ngx_thread_pool_cycle(void *data)
272
+ {
273
+ ngx_thread_pool_t *tp = data;
274
+
275
+ int err;
276
+ sigset_t set;
277
+ ngx_thread_task_t *task;
278
+
279
+ #if 0
280
+ ngx_time_update();
281
+ #endif
282
+
283
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, tp->log, 0,
284
+ "thread in pool \"%V\" started", &tp->name);
285
+
286
+ sigfillset(&set);
287
+
288
+ sigdelset(&set, SIGILL);
289
+ sigdelset(&set, SIGFPE);
290
+ sigdelset(&set, SIGSEGV);
291
+ sigdelset(&set, SIGBUS);
292
+
293
+ err = pthread_sigmask(SIG_BLOCK, &set, NULL);
294
+ if (err) {
295
+ ngx_log_error(NGX_LOG_ALERT, tp->log, err, "pthread_sigmask() failed");
296
+ return NULL;
297
+ }
298
+
299
+ for ( ;; ) {
300
+ if (ngx_thread_mutex_lock(&tp->mtx, tp->log) != NGX_OK) {
301
+ return NULL;
302
+ }
303
+
304
+ /* the number may become negative */
305
+ tp->waiting--;
306
+
307
+ while (tp->queue.first == NULL) {
308
+ if (ngx_thread_cond_wait(&tp->cond, &tp->mtx, tp->log)
309
+ != NGX_OK)
310
+ {
311
+ (void) ngx_thread_mutex_unlock(&tp->mtx, tp->log);
312
+ return NULL;
313
+ }
314
+ }
315
+
316
+ task = tp->queue.first;
317
+ tp->queue.first = task->next;
318
+
319
+ if (tp->queue.first == NULL) {
320
+ tp->queue.last = &tp->queue.first;
321
+ }
322
+
323
+ if (ngx_thread_mutex_unlock(&tp->mtx, tp->log) != NGX_OK) {
324
+ return NULL;
325
+ }
326
+
327
+ #if 0
328
+ ngx_time_update();
329
+ #endif
330
+
331
+ ngx_log_debug2(NGX_LOG_DEBUG_CORE, tp->log, 0,
332
+ "run task #%ui in thread pool \"%V\"",
333
+ task->id, &tp->name);
334
+
335
+ task->handler(task->ctx, tp->log);
336
+
337
+ ngx_log_debug2(NGX_LOG_DEBUG_CORE, tp->log, 0,
338
+ "complete task #%ui in thread pool \"%V\"",
339
+ task->id, &tp->name);
340
+
341
+ task->next = NULL;
342
+
343
+ ngx_spinlock(&ngx_thread_pool_done_lock, 1, 2048);
344
+
345
+ *ngx_thread_pool_done.last = task;
346
+ ngx_thread_pool_done.last = &task->next;
347
+
348
+ ngx_unlock(&ngx_thread_pool_done_lock);
349
+
350
+ (void) ngx_notify(ngx_thread_pool_handler);
351
+ }
352
+ }
353
+
354
+
355
+ static void
356
+ ngx_thread_pool_handler(ngx_event_t *ev)
357
+ {
358
+ ngx_event_t *event;
359
+ ngx_thread_task_t *task;
360
+
361
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, ev->log, 0, "thread pool handler");
362
+
363
+ ngx_spinlock(&ngx_thread_pool_done_lock, 1, 2048);
364
+
365
+ task = ngx_thread_pool_done.first;
366
+ ngx_thread_pool_done.first = NULL;
367
+ ngx_thread_pool_done.last = &ngx_thread_pool_done.first;
368
+
369
+ ngx_unlock(&ngx_thread_pool_done_lock);
370
+
371
+ while (task) {
372
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0,
373
+ "run completion handler for task #%ui", task->id);
374
+
375
+ event = &task->event;
376
+ task = task->next;
377
+
378
+ event->complete = 1;
379
+ event->active = 0;
380
+
381
+ event->handler(event);
382
+ }
383
+ }
384
+
385
+
386
+ static void *
387
+ ngx_thread_pool_create_conf(ngx_cycle_t *cycle)
388
+ {
389
+ ngx_thread_pool_conf_t *tcf;
390
+
391
+ tcf = ngx_pcalloc(cycle->pool, sizeof(ngx_thread_pool_conf_t));
392
+ if (tcf == NULL) {
393
+ return NULL;
394
+ }
395
+
396
+ if (ngx_array_init(&tcf->pools, cycle->pool, 4,
397
+ sizeof(ngx_thread_pool_t *))
398
+ != NGX_OK)
399
+ {
400
+ return NULL;
401
+ }
402
+
403
+ return tcf;
404
+ }
405
+
406
+
407
+ static char *
408
+ ngx_thread_pool_init_conf(ngx_cycle_t *cycle, void *conf)
409
+ {
410
+ ngx_thread_pool_conf_t *tcf = conf;
411
+
412
+ ngx_uint_t i;
413
+ ngx_thread_pool_t **tpp;
414
+
415
+ tpp = tcf->pools.elts;
416
+
417
+ for (i = 0; i < tcf->pools.nelts; i++) {
418
+
419
+ if (tpp[i]->threads) {
420
+ continue;
421
+ }
422
+
423
+ if (tpp[i]->name.len == ngx_thread_pool_default.len
424
+ && ngx_strncmp(tpp[i]->name.data, ngx_thread_pool_default.data,
425
+ ngx_thread_pool_default.len)
426
+ == 0)
427
+ {
428
+ tpp[i]->threads = 32;
429
+ tpp[i]->max_queue = 65536;
430
+ continue;
431
+ }
432
+
433
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
434
+ "unknown thread pool \"%V\" in %s:%ui",
435
+ &tpp[i]->name, tpp[i]->file, tpp[i]->line);
436
+
437
+ return NGX_CONF_ERROR;
438
+ }
439
+
440
+ return NGX_CONF_OK;
441
+ }
442
+
443
+
444
+ static char *
445
+ ngx_thread_pool(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
446
+ {
447
+ ngx_str_t *value;
448
+ ngx_uint_t i;
449
+ ngx_thread_pool_t *tp;
450
+
451
+ value = cf->args->elts;
452
+
453
+ tp = ngx_thread_pool_add(cf, &value[1]);
454
+
455
+ if (tp == NULL) {
456
+ return NGX_CONF_ERROR;
457
+ }
458
+
459
+ if (tp->threads) {
460
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
461
+ "duplicate thread pool \"%V\"", &tp->name);
462
+ return NGX_CONF_ERROR;
463
+ }
464
+
465
+ tp->max_queue = 65536;
466
+
467
+ for (i = 2; i < cf->args->nelts; i++) {
468
+
469
+ if (ngx_strncmp(value[i].data, "threads=", 8) == 0) {
470
+
471
+ tp->threads = ngx_atoi(value[i].data + 8, value[i].len - 8);
472
+
473
+ if (tp->threads == (ngx_uint_t) NGX_ERROR || tp->threads == 0) {
474
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
475
+ "invalid threads value \"%V\"", &value[i]);
476
+ return NGX_CONF_ERROR;
477
+ }
478
+
479
+ continue;
480
+ }
481
+
482
+ if (ngx_strncmp(value[i].data, "max_queue=", 10) == 0) {
483
+
484
+ tp->max_queue = ngx_atoi(value[i].data + 10, value[i].len - 10);
485
+
486
+ if (tp->max_queue == NGX_ERROR) {
487
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
488
+ "invalid max_queue value \"%V\"", &value[i]);
489
+ return NGX_CONF_ERROR;
490
+ }
491
+
492
+ continue;
493
+ }
494
+ }
495
+
496
+ if (tp->threads == 0) {
497
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
498
+ "\"%V\" must have \"threads\" parameter",
499
+ &cmd->name);
500
+ return NGX_CONF_ERROR;
501
+ }
502
+
503
+ return NGX_CONF_OK;
504
+ }
505
+
506
+
507
+ ngx_thread_pool_t *
508
+ ngx_thread_pool_add(ngx_conf_t *cf, ngx_str_t *name)
509
+ {
510
+ ngx_thread_pool_t *tp, **tpp;
511
+ ngx_thread_pool_conf_t *tcf;
512
+
513
+ if (name == NULL) {
514
+ name = &ngx_thread_pool_default;
515
+ }
516
+
517
+ tp = ngx_thread_pool_get(cf->cycle, name);
518
+
519
+ if (tp) {
520
+ return tp;
521
+ }
522
+
523
+ tp = ngx_pcalloc(cf->pool, sizeof(ngx_thread_pool_t));
524
+ if (tp == NULL) {
525
+ return NULL;
526
+ }
527
+
528
+ tp->name = *name;
529
+ tp->file = cf->conf_file->file.name.data;
530
+ tp->line = cf->conf_file->line;
531
+
532
+ tcf = (ngx_thread_pool_conf_t *) ngx_get_conf(cf->cycle->conf_ctx,
533
+ ngx_thread_pool_module);
534
+
535
+ tpp = ngx_array_push(&tcf->pools);
536
+ if (tpp == NULL) {
537
+ return NULL;
538
+ }
539
+
540
+ *tpp = tp;
541
+
542
+ return tp;
543
+ }
544
+
545
+
546
+ ngx_thread_pool_t *
547
+ ngx_thread_pool_get(ngx_cycle_t *cycle, ngx_str_t *name)
548
+ {
549
+ ngx_uint_t i;
550
+ ngx_thread_pool_t **tpp;
551
+ ngx_thread_pool_conf_t *tcf;
552
+
553
+ tcf = (ngx_thread_pool_conf_t *) ngx_get_conf(cycle->conf_ctx,
554
+ ngx_thread_pool_module);
555
+
556
+ tpp = tcf->pools.elts;
557
+
558
+ for (i = 0; i < tcf->pools.nelts; i++) {
559
+
560
+ if (tpp[i]->name.len == name->len
561
+ && ngx_strncmp(tpp[i]->name.data, name->data, name->len) == 0)
562
+ {
563
+ return tpp[i];
564
+ }
565
+ }
566
+
567
+ return NULL;
568
+ }
569
+
570
+
571
+ static ngx_int_t
572
+ ngx_thread_pool_init_worker(ngx_cycle_t *cycle)
573
+ {
574
+ ngx_uint_t i;
575
+ ngx_thread_pool_t **tpp;
576
+ ngx_thread_pool_conf_t *tcf;
577
+
578
+ if (ngx_process != NGX_PROCESS_WORKER
579
+ && ngx_process != NGX_PROCESS_SINGLE)
580
+ {
581
+ return NGX_OK;
582
+ }
583
+
584
+ tcf = (ngx_thread_pool_conf_t *) ngx_get_conf(cycle->conf_ctx,
585
+ ngx_thread_pool_module);
586
+
587
+ if (tcf == NULL) {
588
+ return NGX_OK;
589
+ }
590
+
591
+ ngx_thread_pool_queue_init(&ngx_thread_pool_done);
592
+
593
+ tpp = tcf->pools.elts;
594
+
595
+ for (i = 0; i < tcf->pools.nelts; i++) {
596
+ if (ngx_thread_pool_init(tpp[i], cycle->log, cycle->pool) != NGX_OK) {
597
+ return NGX_ERROR;
598
+ }
599
+ }
600
+
601
+ return NGX_OK;
602
+ }
603
+
604
+
605
+ static void
606
+ ngx_thread_pool_exit_worker(ngx_cycle_t *cycle)
607
+ {
608
+ ngx_uint_t i;
609
+ ngx_thread_pool_t **tpp;
610
+ ngx_thread_pool_conf_t *tcf;
611
+
612
+ if (ngx_process != NGX_PROCESS_WORKER
613
+ && ngx_process != NGX_PROCESS_SINGLE)
614
+ {
615
+ return;
616
+ }
617
+
618
+ tcf = (ngx_thread_pool_conf_t *) ngx_get_conf(cycle->conf_ctx,
619
+ ngx_thread_pool_module);
620
+
621
+ if (tcf == NULL) {
622
+ return;
623
+ }
624
+
625
+ tpp = tcf->pools.elts;
626
+
627
+ for (i = 0; i < tcf->pools.nelts; i++) {
628
+ ngx_thread_pool_destroy(tpp[i]);
629
+ }
630
+ }