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.
- checksums.yaml +4 -4
- data/bin/nginxtra +1 -1
- data/bin/nginxtra_rails +1 -1
- data/lib/nginxtra/version.rb +1 -1
- data/vendor/nginx/CHANGES +358 -14
- data/vendor/nginx/CHANGES.ru +372 -18
- data/vendor/nginx/LICENSE +2 -2
- data/vendor/nginx/auto/cc/clang +5 -0
- data/vendor/nginx/auto/cc/gcc +5 -0
- data/vendor/nginx/auto/lib/google-perftools/conf +1 -1
- data/vendor/nginx/auto/lib/openssl/make +0 -5
- data/vendor/nginx/auto/lib/perl/conf +9 -1
- data/vendor/nginx/auto/make +1 -1
- data/vendor/nginx/auto/modules +11 -0
- data/vendor/nginx/auto/options +10 -2
- data/vendor/nginx/auto/os/darwin +0 -1
- data/vendor/nginx/auto/os/freebsd +6 -23
- data/vendor/nginx/auto/sources +16 -14
- data/vendor/nginx/auto/summary +3 -24
- data/vendor/nginx/auto/threads +20 -0
- data/vendor/nginx/auto/types/sizeof +2 -12
- data/vendor/nginx/auto/unix +50 -6
- data/vendor/nginx/configure +5 -0
- data/vendor/nginx/contrib/vim/syntax/nginx.vim +183 -50
- data/vendor/nginx/src/core/nginx.c +21 -9
- data/vendor/nginx/src/core/nginx.h +8 -2
- data/vendor/nginx/src/core/ngx_buf.c +88 -0
- data/vendor/nginx/src/core/ngx_buf.h +15 -1
- data/vendor/nginx/src/core/ngx_conf_file.c +4 -1
- data/vendor/nginx/src/core/ngx_connection.c +25 -66
- data/vendor/nginx/src/core/ngx_connection.h +1 -3
- data/vendor/nginx/src/core/ngx_core.h +11 -3
- data/vendor/nginx/src/core/ngx_crypt.c +1 -1
- data/vendor/nginx/src/core/ngx_cycle.c +7 -1
- data/vendor/nginx/src/core/ngx_cycle.h +6 -2
- data/vendor/nginx/src/core/ngx_file.c +13 -5
- data/vendor/nginx/src/core/ngx_file.h +6 -0
- data/vendor/nginx/src/core/ngx_log.c +215 -21
- data/vendor/nginx/src/core/ngx_log.h +9 -1
- data/vendor/nginx/src/core/ngx_output_chain.c +104 -15
- data/vendor/nginx/src/core/ngx_palloc.c +3 -7
- data/vendor/nginx/src/core/ngx_rbtree.c +2 -4
- data/vendor/nginx/src/core/ngx_rbtree.h +2 -4
- data/vendor/nginx/src/core/ngx_regex.c +14 -6
- data/vendor/nginx/src/core/ngx_resolver.c +16 -23
- data/vendor/nginx/src/core/ngx_resolver.h +8 -7
- data/vendor/nginx/src/core/ngx_shmtx.c +1 -1
- data/vendor/nginx/src/core/ngx_slab.c +89 -2
- data/vendor/nginx/src/core/ngx_slab.h +3 -0
- data/vendor/nginx/src/core/ngx_string.c +58 -2
- data/vendor/nginx/src/core/ngx_string.h +1 -0
- data/vendor/nginx/src/core/ngx_syslog.c +374 -0
- data/vendor/nginx/src/core/ngx_syslog.h +30 -0
- data/vendor/nginx/src/core/ngx_thread_pool.c +630 -0
- data/vendor/nginx/src/core/ngx_thread_pool.h +36 -0
- data/vendor/nginx/src/core/ngx_times.c +19 -2
- data/vendor/nginx/src/core/ngx_times.h +1 -0
- data/vendor/nginx/src/event/modules/ngx_aio_module.c +1 -1
- data/vendor/nginx/src/event/modules/ngx_devpoll_module.c +9 -24
- data/vendor/nginx/src/event/modules/ngx_epoll_module.c +152 -28
- data/vendor/nginx/src/event/modules/ngx_eventport_module.c +43 -25
- data/vendor/nginx/src/event/modules/ngx_kqueue_module.c +86 -156
- data/vendor/nginx/src/event/modules/ngx_poll_module.c +21 -37
- data/vendor/nginx/src/event/modules/ngx_rtsig_module.c +15 -27
- data/vendor/nginx/src/event/modules/ngx_select_module.c +10 -12
- data/vendor/nginx/src/event/modules/ngx_win32_select_module.c +7 -9
- data/vendor/nginx/src/event/ngx_event.c +5 -33
- data/vendor/nginx/src/event/ngx_event.h +15 -50
- data/vendor/nginx/src/event/ngx_event_accept.c +11 -10
- data/vendor/nginx/src/event/ngx_event_connect.c +0 -11
- data/vendor/nginx/src/event/ngx_event_connect.h +1 -4
- data/vendor/nginx/src/event/ngx_event_openssl.c +622 -38
- data/vendor/nginx/src/event/ngx_event_openssl.h +20 -2
- data/vendor/nginx/src/event/ngx_event_openssl_stapling.c +5 -1
- data/vendor/nginx/src/event/ngx_event_pipe.c +45 -19
- data/vendor/nginx/src/event/ngx_event_pipe.h +3 -0
- data/vendor/nginx/src/event/ngx_event_posted.c +7 -145
- data/vendor/nginx/src/event/ngx_event_posted.h +12 -39
- data/vendor/nginx/src/event/ngx_event_timer.c +50 -70
- data/vendor/nginx/src/event/ngx_event_timer.h +2 -14
- data/vendor/nginx/src/http/modules/ngx_http_addition_filter_module.c +1 -1
- data/vendor/nginx/src/http/modules/ngx_http_autoindex_module.c +416 -71
- data/vendor/nginx/src/http/modules/ngx_http_charset_filter_module.c +19 -15
- data/vendor/nginx/src/http/modules/ngx_http_dav_module.c +16 -4
- data/vendor/nginx/src/http/modules/ngx_http_fastcgi_module.c +601 -134
- data/vendor/nginx/src/http/modules/ngx_http_geo_module.c +1 -1
- data/vendor/nginx/src/http/modules/ngx_http_geoip_module.c +9 -3
- data/vendor/nginx/src/http/modules/ngx_http_gunzip_filter_module.c +9 -3
- data/vendor/nginx/src/http/modules/ngx_http_gzip_filter_module.c +9 -3
- data/vendor/nginx/src/http/modules/ngx_http_gzip_static_module.c +0 -2
- data/vendor/nginx/src/http/modules/ngx_http_headers_filter_module.c +197 -91
- data/vendor/nginx/src/http/modules/ngx_http_image_filter_module.c +1 -0
- data/vendor/nginx/src/http/modules/ngx_http_limit_conn_module.c +65 -162
- data/vendor/nginx/src/http/modules/ngx_http_limit_req_module.c +53 -67
- data/vendor/nginx/src/http/modules/ngx_http_log_module.c +128 -23
- data/vendor/nginx/src/http/modules/ngx_http_memcached_module.c +25 -6
- data/vendor/nginx/src/http/modules/ngx_http_mp4_module.c +1 -1
- data/vendor/nginx/src/http/modules/ngx_http_not_modified_filter_module.c +39 -13
- data/vendor/nginx/src/http/modules/ngx_http_proxy_module.c +697 -141
- data/vendor/nginx/src/http/modules/ngx_http_rewrite_module.c +5 -1
- data/vendor/nginx/src/http/modules/ngx_http_scgi_module.c +282 -125
- data/vendor/nginx/src/http/modules/ngx_http_ssi_filter_module.c +4 -1
- data/vendor/nginx/src/http/modules/ngx_http_ssl_module.c +44 -1
- data/vendor/nginx/src/http/modules/ngx_http_ssl_module.h +2 -0
- data/vendor/nginx/src/http/modules/ngx_http_stub_status_module.c +10 -8
- data/vendor/nginx/src/http/modules/ngx_http_sub_filter_module.c +18 -3
- data/vendor/nginx/src/http/modules/ngx_http_upstream_hash_module.c +641 -0
- data/vendor/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +1 -1
- data/vendor/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c +3 -21
- data/vendor/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c +0 -5
- data/vendor/nginx/src/http/modules/ngx_http_uwsgi_module.c +449 -125
- data/vendor/nginx/src/http/modules/ngx_http_xslt_filter_module.c +4 -2
- data/vendor/nginx/src/http/modules/perl/ngx_http_perl_module.c +2 -1
- data/vendor/nginx/src/http/ngx_http.c +10 -5
- data/vendor/nginx/src/http/ngx_http.h +4 -4
- data/vendor/nginx/src/http/ngx_http_cache.h +26 -1
- data/vendor/nginx/src/http/ngx_http_copy_filter_module.c +109 -68
- data/vendor/nginx/src/http/ngx_http_core_module.c +191 -46
- data/vendor/nginx/src/http/ngx_http_core_module.h +16 -4
- data/vendor/nginx/src/http/ngx_http_file_cache.c +584 -67
- data/vendor/nginx/src/http/ngx_http_parse.c +55 -4
- data/vendor/nginx/src/http/ngx_http_request.c +14 -6
- data/vendor/nginx/src/http/ngx_http_request.h +12 -4
- data/vendor/nginx/src/http/ngx_http_request_body.c +114 -28
- data/vendor/nginx/src/http/ngx_http_spdy.c +383 -229
- data/vendor/nginx/src/http/ngx_http_spdy.h +8 -5
- data/vendor/nginx/src/http/ngx_http_spdy_filter_module.c +12 -4
- data/vendor/nginx/src/http/ngx_http_special_response.c +2 -2
- data/vendor/nginx/src/http/ngx_http_upstream.c +808 -132
- data/vendor/nginx/src/http/ngx_http_upstream.h +33 -3
- data/vendor/nginx/src/http/ngx_http_upstream_round_robin.c +72 -65
- data/vendor/nginx/src/http/ngx_http_upstream_round_robin.h +1 -2
- data/vendor/nginx/src/http/ngx_http_variables.c +47 -3
- data/vendor/nginx/src/http/ngx_http_write_filter_module.c +15 -6
- data/vendor/nginx/src/mail/ngx_mail.c +2 -3
- data/vendor/nginx/src/mail/ngx_mail.h +2 -0
- data/vendor/nginx/src/mail/ngx_mail_auth_http_module.c +140 -11
- data/vendor/nginx/src/mail/ngx_mail_core_module.c +3 -3
- data/vendor/nginx/src/mail/ngx_mail_handler.c +79 -2
- data/vendor/nginx/src/mail/ngx_mail_imap_module.c +3 -1
- data/vendor/nginx/src/mail/ngx_mail_pop3_module.c +3 -1
- data/vendor/nginx/src/mail/ngx_mail_smtp_module.c +3 -1
- data/vendor/nginx/src/mail/ngx_mail_ssl_module.c +125 -1
- data/vendor/nginx/src/mail/ngx_mail_ssl_module.h +8 -0
- data/vendor/nginx/src/misc/ngx_cpp_test_module.cpp +1 -1
- data/vendor/nginx/src/os/unix/ngx_aio_read_chain.c +1 -1
- data/vendor/nginx/src/os/unix/ngx_channel.c +0 -7
- data/vendor/nginx/src/os/unix/ngx_darwin_config.h +0 -3
- data/vendor/nginx/src/os/unix/ngx_darwin_sendfile_chain.c +44 -208
- data/vendor/nginx/src/os/unix/ngx_file_aio_read.c +25 -17
- data/vendor/nginx/src/os/unix/ngx_files.c +109 -0
- data/vendor/nginx/src/os/unix/ngx_files.h +6 -0
- data/vendor/nginx/src/os/unix/ngx_freebsd_config.h +0 -6
- data/vendor/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c +78 -206
- data/vendor/nginx/src/os/unix/ngx_linux_aio_read.c +25 -14
- data/vendor/nginx/src/os/unix/ngx_linux_config.h +4 -1
- data/vendor/nginx/src/os/unix/ngx_linux_sendfile_chain.c +235 -194
- data/vendor/nginx/src/os/unix/ngx_os.h +25 -3
- data/vendor/nginx/src/os/unix/ngx_posix_init.c +4 -2
- data/vendor/nginx/src/os/unix/ngx_process_cycle.c +13 -195
- data/vendor/nginx/src/os/unix/ngx_process_cycle.h +0 -1
- data/vendor/nginx/src/os/unix/ngx_readv_chain.c +27 -108
- data/vendor/nginx/src/os/unix/ngx_setproctitle.h +2 -2
- data/vendor/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c +12 -67
- data/vendor/nginx/src/os/unix/ngx_thread.h +26 -83
- data/vendor/nginx/src/os/unix/ngx_thread_cond.c +87 -0
- data/vendor/nginx/src/os/unix/ngx_thread_id.c +70 -0
- data/vendor/nginx/src/os/unix/ngx_thread_mutex.c +174 -0
- data/vendor/nginx/src/os/unix/ngx_user.c +2 -20
- data/vendor/nginx/src/os/unix/ngx_writev_chain.c +129 -98
- metadata +16 -17
- data/vendor/nginx/auto/lib/zlib/patch.zlib.h +0 -10
- data/vendor/nginx/src/event/ngx_event_busy_lock.c +0 -286
- data/vendor/nginx/src/event/ngx_event_busy_lock.h +0 -65
- data/vendor/nginx/src/event/ngx_event_mutex.c +0 -70
- data/vendor/nginx/src/http/ngx_http_busy_lock.c +0 -307
- data/vendor/nginx/src/http/ngx_http_busy_lock.h +0 -54
- data/vendor/nginx/src/os/unix/ngx_freebsd_rfork_thread.c +0 -756
- data/vendor/nginx/src/os/unix/ngx_freebsd_rfork_thread.h +0 -122
- data/vendor/nginx/src/os/unix/ngx_pthread_thread.c +0 -278
- data/vendor/nginx/src/os/unix/rfork_thread.S +0 -73
@@ -1,70 +0,0 @@
|
|
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
|
-
#include <ngx_event.h>
|
11
|
-
|
12
|
-
|
13
|
-
ngx_int_t ngx_event_mutex_timedlock(ngx_event_mutex_t *m, ngx_msec_t timer,
|
14
|
-
ngx_event_t *ev)
|
15
|
-
{
|
16
|
-
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
17
|
-
"lock event mutex %p lock:%XD", m, m->lock);
|
18
|
-
|
19
|
-
if (m->lock) {
|
20
|
-
|
21
|
-
if (m->events == NULL) {
|
22
|
-
m->events = ev;
|
23
|
-
|
24
|
-
} else {
|
25
|
-
m->last->next = ev;
|
26
|
-
}
|
27
|
-
|
28
|
-
m->last = ev;
|
29
|
-
ev->next = NULL;
|
30
|
-
|
31
|
-
#if (NGX_THREADS0)
|
32
|
-
ev->light = 1;
|
33
|
-
#endif
|
34
|
-
|
35
|
-
ngx_add_timer(ev, timer);
|
36
|
-
|
37
|
-
return NGX_AGAIN;
|
38
|
-
}
|
39
|
-
|
40
|
-
m->lock = 1;
|
41
|
-
|
42
|
-
return NGX_OK;
|
43
|
-
}
|
44
|
-
|
45
|
-
|
46
|
-
ngx_int_t ngx_event_mutex_unlock(ngx_event_mutex_t *m, ngx_log_t *log)
|
47
|
-
{
|
48
|
-
ngx_event_t *ev;
|
49
|
-
|
50
|
-
if (m->lock == 0) {
|
51
|
-
ngx_log_error(NGX_LOG_ALERT, log, 0,
|
52
|
-
"tring to unlock the free event mutex %p", m);
|
53
|
-
return NGX_ERROR;
|
54
|
-
}
|
55
|
-
|
56
|
-
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
|
57
|
-
"unlock event mutex %p, next event: %p", m, m->events);
|
58
|
-
|
59
|
-
m->lock = 0;
|
60
|
-
|
61
|
-
if (m->events) {
|
62
|
-
ev = m->events;
|
63
|
-
m->events = ev->next;
|
64
|
-
|
65
|
-
ev->next = (ngx_event_t *) ngx_posted_events;
|
66
|
-
ngx_posted_events = ev;
|
67
|
-
}
|
68
|
-
|
69
|
-
return NGX_OK;
|
70
|
-
}
|
@@ -1,307 +0,0 @@
|
|
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
|
-
#include <ngx_http.h>
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
static int ngx_http_busy_lock_look_cacheable(ngx_http_busy_lock_t *bl,
|
15
|
-
ngx_http_busy_lock_ctx_t *bc,
|
16
|
-
int lock);
|
17
|
-
|
18
|
-
|
19
|
-
int ngx_http_busy_lock(ngx_http_busy_lock_t *bl, ngx_http_busy_lock_ctx_t *bc)
|
20
|
-
{
|
21
|
-
if (bl->busy < bl->max_busy) {
|
22
|
-
bl->busy++;
|
23
|
-
|
24
|
-
if (bc->time) {
|
25
|
-
bc->time = 0;
|
26
|
-
bl->waiting--;
|
27
|
-
}
|
28
|
-
|
29
|
-
return NGX_OK;
|
30
|
-
}
|
31
|
-
|
32
|
-
if (bc->time) {
|
33
|
-
if (bc->time < bl->timeout) {
|
34
|
-
ngx_add_timer(bc->event, 1000);
|
35
|
-
return NGX_AGAIN;
|
36
|
-
}
|
37
|
-
|
38
|
-
bl->waiting--;
|
39
|
-
return NGX_DONE;
|
40
|
-
|
41
|
-
}
|
42
|
-
|
43
|
-
if (bl->timeout == 0) {
|
44
|
-
return NGX_DONE;
|
45
|
-
}
|
46
|
-
|
47
|
-
if (bl->waiting < bl->max_waiting) {
|
48
|
-
bl->waiting++;
|
49
|
-
|
50
|
-
#if 0
|
51
|
-
ngx_add_timer(bc->event, 1000);
|
52
|
-
bc->event->event_handler = bc->event_handler;
|
53
|
-
#endif
|
54
|
-
|
55
|
-
/* TODO: ngx_handle_level_read_event() */
|
56
|
-
|
57
|
-
return NGX_AGAIN;
|
58
|
-
}
|
59
|
-
|
60
|
-
return NGX_ERROR;
|
61
|
-
}
|
62
|
-
|
63
|
-
|
64
|
-
int ngx_http_busy_lock_cacheable(ngx_http_busy_lock_t *bl,
|
65
|
-
ngx_http_busy_lock_ctx_t *bc, int lock)
|
66
|
-
{
|
67
|
-
int rc;
|
68
|
-
|
69
|
-
rc = ngx_http_busy_lock_look_cacheable(bl, bc, lock);
|
70
|
-
|
71
|
-
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, bc->event->log, 0,
|
72
|
-
"http busylock: %d w:%d mw::%d",
|
73
|
-
rc, bl->waiting, bl->max_waiting);
|
74
|
-
|
75
|
-
if (rc == NGX_OK) { /* no the same request, there's free slot */
|
76
|
-
return NGX_OK;
|
77
|
-
}
|
78
|
-
|
79
|
-
if (rc == NGX_ERROR && !lock) { /* no the same request, no free slot */
|
80
|
-
return NGX_OK;
|
81
|
-
}
|
82
|
-
|
83
|
-
/* rc == NGX_AGAIN: the same request */
|
84
|
-
|
85
|
-
if (bc->time) {
|
86
|
-
if (bc->time < bl->timeout) {
|
87
|
-
ngx_add_timer(bc->event, 1000);
|
88
|
-
return NGX_AGAIN;
|
89
|
-
}
|
90
|
-
|
91
|
-
bl->waiting--;
|
92
|
-
return NGX_DONE;
|
93
|
-
|
94
|
-
}
|
95
|
-
|
96
|
-
if (bl->timeout == 0) {
|
97
|
-
return NGX_DONE;
|
98
|
-
}
|
99
|
-
|
100
|
-
if (bl->waiting < bl->max_waiting) {
|
101
|
-
#if 0
|
102
|
-
bl->waiting++;
|
103
|
-
ngx_add_timer(bc->event, 1000);
|
104
|
-
bc->event->event_handler = bc->event_handler;
|
105
|
-
#endif
|
106
|
-
|
107
|
-
/* TODO: ngx_handle_level_read_event() */
|
108
|
-
|
109
|
-
return NGX_AGAIN;
|
110
|
-
}
|
111
|
-
|
112
|
-
return NGX_ERROR;
|
113
|
-
}
|
114
|
-
|
115
|
-
|
116
|
-
void ngx_http_busy_unlock(ngx_http_busy_lock_t *bl,
|
117
|
-
ngx_http_busy_lock_ctx_t *bc)
|
118
|
-
{
|
119
|
-
if (bl == NULL) {
|
120
|
-
return;
|
121
|
-
}
|
122
|
-
|
123
|
-
if (bl->md5) {
|
124
|
-
bl->md5_mask[bc->slot / 8] &= ~(1 << (bc->slot & 7));
|
125
|
-
bl->cacheable--;
|
126
|
-
}
|
127
|
-
|
128
|
-
bl->busy--;
|
129
|
-
}
|
130
|
-
|
131
|
-
|
132
|
-
static int ngx_http_busy_lock_look_cacheable(ngx_http_busy_lock_t *bl,
|
133
|
-
ngx_http_busy_lock_ctx_t *bc,
|
134
|
-
int lock)
|
135
|
-
{
|
136
|
-
int i, b, cacheable, free;
|
137
|
-
u_int mask;
|
138
|
-
|
139
|
-
b = 0;
|
140
|
-
cacheable = 0;
|
141
|
-
free = -1;
|
142
|
-
|
143
|
-
#if (NGX_SUPPRESS_WARN)
|
144
|
-
mask = 0;
|
145
|
-
#endif
|
146
|
-
|
147
|
-
for (i = 0; i < bl->max_busy; i++) {
|
148
|
-
|
149
|
-
if ((b & 7) == 0) {
|
150
|
-
mask = bl->md5_mask[i / 8];
|
151
|
-
}
|
152
|
-
|
153
|
-
if (mask & 1) {
|
154
|
-
if (ngx_memcmp(&bl->md5[i * 16], bc->md5, 16) == 0) {
|
155
|
-
return NGX_AGAIN;
|
156
|
-
}
|
157
|
-
cacheable++;
|
158
|
-
|
159
|
-
} else if (free == -1) {
|
160
|
-
free = i;
|
161
|
-
}
|
162
|
-
|
163
|
-
#if 1
|
164
|
-
if (cacheable == bl->cacheable) {
|
165
|
-
if (free == -1 && cacheable < bl->max_busy) {
|
166
|
-
free = i + 1;
|
167
|
-
}
|
168
|
-
|
169
|
-
break;
|
170
|
-
}
|
171
|
-
#endif
|
172
|
-
|
173
|
-
mask >>= 1;
|
174
|
-
b++;
|
175
|
-
}
|
176
|
-
|
177
|
-
if (free == -1) {
|
178
|
-
return NGX_ERROR;
|
179
|
-
}
|
180
|
-
|
181
|
-
if (lock) {
|
182
|
-
if (bl->busy == bl->max_busy) {
|
183
|
-
return NGX_ERROR;
|
184
|
-
}
|
185
|
-
|
186
|
-
ngx_memcpy(&bl->md5[free * 16], bc->md5, 16);
|
187
|
-
bl->md5_mask[free / 8] |= 1 << (free & 7);
|
188
|
-
bc->slot = free;
|
189
|
-
|
190
|
-
bl->cacheable++;
|
191
|
-
bl->busy++;
|
192
|
-
}
|
193
|
-
|
194
|
-
return NGX_OK;
|
195
|
-
}
|
196
|
-
|
197
|
-
|
198
|
-
char *ngx_http_set_busy_lock_slot(ngx_conf_t *cf, ngx_command_t *cmd,
|
199
|
-
void *conf)
|
200
|
-
{
|
201
|
-
char *p = conf;
|
202
|
-
|
203
|
-
ngx_uint_t i, dup, invalid;
|
204
|
-
ngx_str_t *value, line;
|
205
|
-
ngx_http_busy_lock_t *bl, **blp;
|
206
|
-
|
207
|
-
blp = (ngx_http_busy_lock_t **) (p + cmd->offset);
|
208
|
-
if (*blp) {
|
209
|
-
return "is duplicate";
|
210
|
-
}
|
211
|
-
|
212
|
-
/* ngx_calloc_shared() */
|
213
|
-
bl = ngx_pcalloc(cf->pool, sizeof(ngx_http_busy_lock_t));
|
214
|
-
if (bl == NULL) {
|
215
|
-
return NGX_CONF_ERROR;
|
216
|
-
}
|
217
|
-
*blp = bl;
|
218
|
-
|
219
|
-
/* ngx_calloc_shared() */
|
220
|
-
bl->mutex = ngx_pcalloc(cf->pool, sizeof(ngx_event_mutex_t));
|
221
|
-
if (bl->mutex == NULL) {
|
222
|
-
return NGX_CONF_ERROR;
|
223
|
-
}
|
224
|
-
|
225
|
-
dup = 0;
|
226
|
-
invalid = 0;
|
227
|
-
value = cf->args->elts;
|
228
|
-
|
229
|
-
for (i = 1; i < cf->args->nelts; i++) {
|
230
|
-
|
231
|
-
if (value[i].data[1] != '=') {
|
232
|
-
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
233
|
-
"invalid value \"%s\"", value[i].data);
|
234
|
-
return NGX_CONF_ERROR;
|
235
|
-
}
|
236
|
-
|
237
|
-
switch (value[i].data[0]) {
|
238
|
-
|
239
|
-
case 'b':
|
240
|
-
if (bl->max_busy) {
|
241
|
-
dup = 1;
|
242
|
-
break;
|
243
|
-
}
|
244
|
-
|
245
|
-
bl->max_busy = ngx_atoi(value[i].data + 2, value[i].len - 2);
|
246
|
-
if (bl->max_busy == NGX_ERROR) {
|
247
|
-
invalid = 1;
|
248
|
-
break;
|
249
|
-
}
|
250
|
-
|
251
|
-
continue;
|
252
|
-
|
253
|
-
case 'w':
|
254
|
-
if (bl->max_waiting) {
|
255
|
-
dup = 1;
|
256
|
-
break;
|
257
|
-
}
|
258
|
-
|
259
|
-
bl->max_waiting = ngx_atoi(value[i].data + 2, value[i].len - 2);
|
260
|
-
if (bl->max_waiting == NGX_ERROR) {
|
261
|
-
invalid = 1;
|
262
|
-
break;
|
263
|
-
}
|
264
|
-
|
265
|
-
continue;
|
266
|
-
|
267
|
-
case 't':
|
268
|
-
if (bl->timeout) {
|
269
|
-
dup = 1;
|
270
|
-
break;
|
271
|
-
}
|
272
|
-
|
273
|
-
line.len = value[i].len - 2;
|
274
|
-
line.data = value[i].data + 2;
|
275
|
-
|
276
|
-
bl->timeout = ngx_parse_time(&line, 1);
|
277
|
-
if (bl->timeout == (time_t) NGX_ERROR) {
|
278
|
-
invalid = 1;
|
279
|
-
break;
|
280
|
-
}
|
281
|
-
|
282
|
-
continue;
|
283
|
-
|
284
|
-
default:
|
285
|
-
invalid = 1;
|
286
|
-
}
|
287
|
-
|
288
|
-
if (dup) {
|
289
|
-
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
290
|
-
"duplicate value \"%s\"", value[i].data);
|
291
|
-
return NGX_CONF_ERROR;
|
292
|
-
}
|
293
|
-
|
294
|
-
if (invalid) {
|
295
|
-
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
296
|
-
"invalid value \"%s\"", value[i].data);
|
297
|
-
return NGX_CONF_ERROR;
|
298
|
-
}
|
299
|
-
}
|
300
|
-
|
301
|
-
if (bl->timeout == 0 && bl->max_waiting) {
|
302
|
-
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
303
|
-
"busy lock waiting is useless with zero timeout, ignoring");
|
304
|
-
}
|
305
|
-
|
306
|
-
return NGX_CONF_OK;
|
307
|
-
}
|
@@ -1,54 +0,0 @@
|
|
1
|
-
|
2
|
-
/*
|
3
|
-
* Copyright (C) Igor Sysoev
|
4
|
-
* Copyright (C) Nginx, Inc.
|
5
|
-
*/
|
6
|
-
|
7
|
-
|
8
|
-
#ifndef _NGX_HTTP_BUSY_LOCK_H_INCLUDED_
|
9
|
-
#define _NGX_HTTP_BUSY_LOCK_H_INCLUDED_
|
10
|
-
|
11
|
-
|
12
|
-
#include <ngx_config.h>
|
13
|
-
#include <ngx_core.h>
|
14
|
-
#include <ngx_event.h>
|
15
|
-
#include <ngx_http.h>
|
16
|
-
|
17
|
-
|
18
|
-
typedef struct {
|
19
|
-
u_char *md5_mask;
|
20
|
-
char *md5;
|
21
|
-
int cacheable;
|
22
|
-
|
23
|
-
int busy;
|
24
|
-
int max_busy;
|
25
|
-
|
26
|
-
int waiting;
|
27
|
-
int max_waiting;
|
28
|
-
|
29
|
-
time_t timeout;
|
30
|
-
|
31
|
-
ngx_event_mutex_t *mutex;
|
32
|
-
} ngx_http_busy_lock_t;
|
33
|
-
|
34
|
-
|
35
|
-
typedef struct {
|
36
|
-
time_t time;
|
37
|
-
ngx_event_t *event;
|
38
|
-
void (*event_handler)(ngx_event_t *ev);
|
39
|
-
u_char *md5;
|
40
|
-
int slot;
|
41
|
-
} ngx_http_busy_lock_ctx_t;
|
42
|
-
|
43
|
-
|
44
|
-
int ngx_http_busy_lock(ngx_http_busy_lock_t *bl, ngx_http_busy_lock_ctx_t *bc);
|
45
|
-
int ngx_http_busy_lock_cacheable(ngx_http_busy_lock_t *bl,
|
46
|
-
ngx_http_busy_lock_ctx_t *bc, int lock);
|
47
|
-
void ngx_http_busy_unlock(ngx_http_busy_lock_t *bl,
|
48
|
-
ngx_http_busy_lock_ctx_t *bc);
|
49
|
-
|
50
|
-
char *ngx_http_set_busy_lock_slot(ngx_conf_t *cf, ngx_command_t *cmd,
|
51
|
-
void *conf);
|
52
|
-
|
53
|
-
|
54
|
-
#endif /* _NGX_HTTP_BUSY_LOCK_H_INCLUDED_ */
|
@@ -1,756 +0,0 @@
|
|
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
|
-
* The threads implementation uses the rfork(RFPROC|RFTHREAD|RFMEM) syscall
|
13
|
-
* to create threads. All threads use the stacks of the same size mmap()ed
|
14
|
-
* below the main stack. Thus the current thread id is determined via
|
15
|
-
* the stack pointer value.
|
16
|
-
*
|
17
|
-
* The mutex implementation uses the ngx_atomic_cmp_set() operation
|
18
|
-
* to acquire a mutex and the SysV semaphore to wait on a mutex and to wake up
|
19
|
-
* the waiting threads. The light mutex does not use semaphore, so after
|
20
|
-
* spinning in the lock the thread calls sched_yield(). However the light
|
21
|
-
* mutexes are intended to be used with the "trylock" operation only.
|
22
|
-
* The SysV semop() is a cheap syscall, particularly if it has little sembuf's
|
23
|
-
* and does not use SEM_UNDO.
|
24
|
-
*
|
25
|
-
* The condition variable implementation uses the signal #64.
|
26
|
-
* The signal handler is SIG_IGN so the kill() is a cheap syscall.
|
27
|
-
* The thread waits a signal in kevent(). The use of the EVFILT_SIGNAL
|
28
|
-
* is safe since FreeBSD 4.10-STABLE.
|
29
|
-
*
|
30
|
-
* This threads implementation currently works on i386 (486+) and amd64
|
31
|
-
* platforms only.
|
32
|
-
*/
|
33
|
-
|
34
|
-
|
35
|
-
char *ngx_freebsd_kern_usrstack;
|
36
|
-
size_t ngx_thread_stack_size;
|
37
|
-
|
38
|
-
|
39
|
-
static size_t rz_size;
|
40
|
-
static size_t usable_stack_size;
|
41
|
-
static char *last_stack;
|
42
|
-
|
43
|
-
static ngx_uint_t nthreads;
|
44
|
-
static ngx_uint_t max_threads;
|
45
|
-
|
46
|
-
static ngx_uint_t nkeys;
|
47
|
-
static ngx_tid_t *tids; /* the threads tids array */
|
48
|
-
void **ngx_tls; /* the threads tls's array */
|
49
|
-
|
50
|
-
/* the thread-safe libc errno */
|
51
|
-
|
52
|
-
static int errno0; /* the main thread's errno */
|
53
|
-
static int *errnos; /* the threads errno's array */
|
54
|
-
|
55
|
-
int *
|
56
|
-
__error()
|
57
|
-
{
|
58
|
-
int tid;
|
59
|
-
|
60
|
-
tid = ngx_gettid();
|
61
|
-
|
62
|
-
return tid ? &errnos[tid - 1] : &errno0;
|
63
|
-
}
|
64
|
-
|
65
|
-
|
66
|
-
/*
|
67
|
-
* __isthreaded enables the spinlocks in some libc functions, i.e. in malloc()
|
68
|
-
* and some other places. Nevertheless we protect our malloc()/free() calls
|
69
|
-
* by own mutex that is more efficient than the spinlock.
|
70
|
-
*
|
71
|
-
* _spinlock() is a weak referenced stub in src/lib/libc/gen/_spinlock_stub.c
|
72
|
-
* that does nothing.
|
73
|
-
*/
|
74
|
-
|
75
|
-
extern int __isthreaded;
|
76
|
-
|
77
|
-
void
|
78
|
-
_spinlock(ngx_atomic_t *lock)
|
79
|
-
{
|
80
|
-
ngx_int_t tries;
|
81
|
-
|
82
|
-
tries = 0;
|
83
|
-
|
84
|
-
for ( ;; ) {
|
85
|
-
|
86
|
-
if (*lock) {
|
87
|
-
if (ngx_ncpu > 1 && tries++ < 1000) {
|
88
|
-
continue;
|
89
|
-
}
|
90
|
-
|
91
|
-
sched_yield();
|
92
|
-
tries = 0;
|
93
|
-
|
94
|
-
} else {
|
95
|
-
if (ngx_atomic_cmp_set(lock, 0, 1)) {
|
96
|
-
return;
|
97
|
-
}
|
98
|
-
}
|
99
|
-
}
|
100
|
-
}
|
101
|
-
|
102
|
-
|
103
|
-
/*
|
104
|
-
* Before FreeBSD 5.1 _spinunlock() is a simple #define in
|
105
|
-
* src/lib/libc/include/spinlock.h that zeroes lock.
|
106
|
-
*
|
107
|
-
* Since FreeBSD 5.1 _spinunlock() is a weak referenced stub in
|
108
|
-
* src/lib/libc/gen/_spinlock_stub.c that does nothing.
|
109
|
-
*/
|
110
|
-
|
111
|
-
#ifndef _spinunlock
|
112
|
-
|
113
|
-
void
|
114
|
-
_spinunlock(ngx_atomic_t *lock)
|
115
|
-
{
|
116
|
-
*lock = 0;
|
117
|
-
}
|
118
|
-
|
119
|
-
#endif
|
120
|
-
|
121
|
-
|
122
|
-
ngx_err_t
|
123
|
-
ngx_create_thread(ngx_tid_t *tid, ngx_thread_value_t (*func)(void *arg),
|
124
|
-
void *arg, ngx_log_t *log)
|
125
|
-
{
|
126
|
-
ngx_pid_t id;
|
127
|
-
ngx_err_t err;
|
128
|
-
char *stack, *stack_top;
|
129
|
-
|
130
|
-
if (nthreads >= max_threads) {
|
131
|
-
ngx_log_error(NGX_LOG_CRIT, log, 0,
|
132
|
-
"no more than %ui threads can be created", max_threads);
|
133
|
-
return NGX_ERROR;
|
134
|
-
}
|
135
|
-
|
136
|
-
last_stack -= ngx_thread_stack_size;
|
137
|
-
|
138
|
-
stack = mmap(last_stack, usable_stack_size, PROT_READ|PROT_WRITE,
|
139
|
-
MAP_STACK, -1, 0);
|
140
|
-
|
141
|
-
if (stack == MAP_FAILED) {
|
142
|
-
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
|
143
|
-
"mmap(%p:%uz, MAP_STACK) thread stack failed",
|
144
|
-
last_stack, usable_stack_size);
|
145
|
-
return NGX_ERROR;
|
146
|
-
}
|
147
|
-
|
148
|
-
if (stack != last_stack) {
|
149
|
-
ngx_log_error(NGX_LOG_ALERT, log, 0,
|
150
|
-
"stack %p address was changed to %p", last_stack, stack);
|
151
|
-
return NGX_ERROR;
|
152
|
-
}
|
153
|
-
|
154
|
-
stack_top = stack + usable_stack_size;
|
155
|
-
|
156
|
-
ngx_log_debug2(NGX_LOG_DEBUG_CORE, log, 0,
|
157
|
-
"thread stack: %p-%p", stack, stack_top);
|
158
|
-
|
159
|
-
ngx_set_errno(0);
|
160
|
-
|
161
|
-
id = rfork_thread(RFPROC|RFTHREAD|RFMEM, stack_top,
|
162
|
-
(ngx_rfork_thread_func_pt) func, arg);
|
163
|
-
|
164
|
-
err = ngx_errno;
|
165
|
-
|
166
|
-
if (id == -1) {
|
167
|
-
ngx_log_error(NGX_LOG_ALERT, log, err, "rfork() failed");
|
168
|
-
|
169
|
-
} else {
|
170
|
-
*tid = id;
|
171
|
-
nthreads = (ngx_freebsd_kern_usrstack - stack_top)
|
172
|
-
/ ngx_thread_stack_size;
|
173
|
-
tids[nthreads] = id;
|
174
|
-
|
175
|
-
ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "rfork()ed thread: %P", id);
|
176
|
-
}
|
177
|
-
|
178
|
-
return err;
|
179
|
-
}
|
180
|
-
|
181
|
-
|
182
|
-
ngx_int_t
|
183
|
-
ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle)
|
184
|
-
{
|
185
|
-
char *red_zone, *zone;
|
186
|
-
size_t len;
|
187
|
-
ngx_int_t i;
|
188
|
-
struct sigaction sa;
|
189
|
-
|
190
|
-
max_threads = n + 1;
|
191
|
-
|
192
|
-
for (i = 0; i < n; i++) {
|
193
|
-
ngx_memzero(&sa, sizeof(struct sigaction));
|
194
|
-
sa.sa_handler = SIG_IGN;
|
195
|
-
sigemptyset(&sa.sa_mask);
|
196
|
-
if (sigaction(NGX_CV_SIGNAL, &sa, NULL) == -1) {
|
197
|
-
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
198
|
-
"sigaction(%d, SIG_IGN) failed", NGX_CV_SIGNAL);
|
199
|
-
return NGX_ERROR;
|
200
|
-
}
|
201
|
-
}
|
202
|
-
|
203
|
-
len = sizeof(ngx_freebsd_kern_usrstack);
|
204
|
-
if (sysctlbyname("kern.usrstack", &ngx_freebsd_kern_usrstack, &len,
|
205
|
-
NULL, 0) == -1)
|
206
|
-
{
|
207
|
-
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
208
|
-
"sysctlbyname(kern.usrstack) failed");
|
209
|
-
return NGX_ERROR;
|
210
|
-
}
|
211
|
-
|
212
|
-
/* the main thread stack red zone */
|
213
|
-
rz_size = ngx_pagesize;
|
214
|
-
red_zone = ngx_freebsd_kern_usrstack - (size + rz_size);
|
215
|
-
|
216
|
-
ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
|
217
|
-
"usrstack: %p red zone: %p",
|
218
|
-
ngx_freebsd_kern_usrstack, red_zone);
|
219
|
-
|
220
|
-
zone = mmap(red_zone, rz_size, PROT_NONE, MAP_ANON, -1, 0);
|
221
|
-
if (zone == MAP_FAILED) {
|
222
|
-
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
223
|
-
"mmap(%p:%uz, PROT_NONE, MAP_ANON) red zone failed",
|
224
|
-
red_zone, rz_size);
|
225
|
-
return NGX_ERROR;
|
226
|
-
}
|
227
|
-
|
228
|
-
if (zone != red_zone) {
|
229
|
-
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
|
230
|
-
"red zone %p address was changed to %p", red_zone, zone);
|
231
|
-
return NGX_ERROR;
|
232
|
-
}
|
233
|
-
|
234
|
-
/* create the thread errno' array */
|
235
|
-
|
236
|
-
errnos = ngx_calloc(n * sizeof(int), cycle->log);
|
237
|
-
if (errnos == NULL) {
|
238
|
-
return NGX_ERROR;
|
239
|
-
}
|
240
|
-
|
241
|
-
/* create the thread tids array */
|
242
|
-
|
243
|
-
tids = ngx_calloc((n + 1) * sizeof(ngx_tid_t), cycle->log);
|
244
|
-
if (tids == NULL) {
|
245
|
-
return NGX_ERROR;
|
246
|
-
}
|
247
|
-
|
248
|
-
tids[0] = ngx_pid;
|
249
|
-
|
250
|
-
/* create the thread tls' array */
|
251
|
-
|
252
|
-
ngx_tls = ngx_calloc(NGX_THREAD_KEYS_MAX * (n + 1) * sizeof(void *),
|
253
|
-
cycle->log);
|
254
|
-
if (ngx_tls == NULL) {
|
255
|
-
return NGX_ERROR;
|
256
|
-
}
|
257
|
-
|
258
|
-
nthreads = 1;
|
259
|
-
|
260
|
-
last_stack = zone + rz_size;
|
261
|
-
usable_stack_size = size;
|
262
|
-
ngx_thread_stack_size = size + rz_size;
|
263
|
-
|
264
|
-
/* allow the spinlock in libc malloc() */
|
265
|
-
__isthreaded = 1;
|
266
|
-
|
267
|
-
ngx_threaded = 1;
|
268
|
-
|
269
|
-
return NGX_OK;
|
270
|
-
}
|
271
|
-
|
272
|
-
|
273
|
-
ngx_tid_t
|
274
|
-
ngx_thread_self(void)
|
275
|
-
{
|
276
|
-
ngx_int_t tid;
|
277
|
-
|
278
|
-
tid = ngx_gettid();
|
279
|
-
|
280
|
-
if (tids == NULL) {
|
281
|
-
return ngx_pid;
|
282
|
-
}
|
283
|
-
|
284
|
-
return tids[tid];
|
285
|
-
}
|
286
|
-
|
287
|
-
|
288
|
-
ngx_err_t
|
289
|
-
ngx_thread_key_create(ngx_tls_key_t *key)
|
290
|
-
{
|
291
|
-
if (nkeys >= NGX_THREAD_KEYS_MAX) {
|
292
|
-
return NGX_ENOMEM;
|
293
|
-
}
|
294
|
-
|
295
|
-
*key = nkeys++;
|
296
|
-
|
297
|
-
return 0;
|
298
|
-
}
|
299
|
-
|
300
|
-
|
301
|
-
ngx_err_t
|
302
|
-
ngx_thread_set_tls(ngx_tls_key_t key, void *value)
|
303
|
-
{
|
304
|
-
if (key >= NGX_THREAD_KEYS_MAX) {
|
305
|
-
return NGX_EINVAL;
|
306
|
-
}
|
307
|
-
|
308
|
-
ngx_tls[key * NGX_THREAD_KEYS_MAX + ngx_gettid()] = value;
|
309
|
-
return 0;
|
310
|
-
}
|
311
|
-
|
312
|
-
|
313
|
-
ngx_mutex_t *
|
314
|
-
ngx_mutex_init(ngx_log_t *log, ngx_uint_t flags)
|
315
|
-
{
|
316
|
-
ngx_mutex_t *m;
|
317
|
-
union semun op;
|
318
|
-
|
319
|
-
m = ngx_alloc(sizeof(ngx_mutex_t), log);
|
320
|
-
if (m == NULL) {
|
321
|
-
return NULL;
|
322
|
-
}
|
323
|
-
|
324
|
-
m->lock = 0;
|
325
|
-
m->log = log;
|
326
|
-
|
327
|
-
if (flags & NGX_MUTEX_LIGHT) {
|
328
|
-
m->semid = -1;
|
329
|
-
return m;
|
330
|
-
}
|
331
|
-
|
332
|
-
m->semid = semget(IPC_PRIVATE, 1, SEM_R|SEM_A);
|
333
|
-
if (m->semid == -1) {
|
334
|
-
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "semget() failed");
|
335
|
-
return NULL;
|
336
|
-
}
|
337
|
-
|
338
|
-
op.val = 0;
|
339
|
-
|
340
|
-
if (semctl(m->semid, 0, SETVAL, op) == -1) {
|
341
|
-
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "semctl(SETVAL) failed");
|
342
|
-
|
343
|
-
if (semctl(m->semid, 0, IPC_RMID) == -1) {
|
344
|
-
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
|
345
|
-
"semctl(IPC_RMID) failed");
|
346
|
-
}
|
347
|
-
|
348
|
-
return NULL;
|
349
|
-
}
|
350
|
-
|
351
|
-
return m;
|
352
|
-
}
|
353
|
-
|
354
|
-
|
355
|
-
void
|
356
|
-
ngx_mutex_destroy(ngx_mutex_t *m)
|
357
|
-
{
|
358
|
-
if (semctl(m->semid, 0, IPC_RMID) == -1) {
|
359
|
-
ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
|
360
|
-
"semctl(IPC_RMID) failed");
|
361
|
-
}
|
362
|
-
|
363
|
-
ngx_free((void *) m);
|
364
|
-
}
|
365
|
-
|
366
|
-
|
367
|
-
ngx_int_t
|
368
|
-
ngx_mutex_dolock(ngx_mutex_t *m, ngx_int_t try)
|
369
|
-
{
|
370
|
-
uint32_t lock, old;
|
371
|
-
ngx_uint_t tries;
|
372
|
-
struct sembuf op;
|
373
|
-
|
374
|
-
if (!ngx_threaded) {
|
375
|
-
return NGX_OK;
|
376
|
-
}
|
377
|
-
|
378
|
-
#if (NGX_DEBUG)
|
379
|
-
if (try) {
|
380
|
-
ngx_log_debug2(NGX_LOG_DEBUG_MUTEX, m->log, 0,
|
381
|
-
"try lock mutex %p lock:%XD", m, m->lock);
|
382
|
-
} else {
|
383
|
-
ngx_log_debug2(NGX_LOG_DEBUG_MUTEX, m->log, 0,
|
384
|
-
"lock mutex %p lock:%XD", m, m->lock);
|
385
|
-
}
|
386
|
-
#endif
|
387
|
-
|
388
|
-
old = m->lock;
|
389
|
-
tries = 0;
|
390
|
-
|
391
|
-
for ( ;; ) {
|
392
|
-
if (old & NGX_MUTEX_LOCK_BUSY) {
|
393
|
-
|
394
|
-
if (try) {
|
395
|
-
return NGX_AGAIN;
|
396
|
-
}
|
397
|
-
|
398
|
-
if (ngx_ncpu > 1 && tries++ < 1000) {
|
399
|
-
|
400
|
-
/* the spinlock is used only on the SMP system */
|
401
|
-
|
402
|
-
old = m->lock;
|
403
|
-
continue;
|
404
|
-
}
|
405
|
-
|
406
|
-
if (m->semid == -1) {
|
407
|
-
sched_yield();
|
408
|
-
|
409
|
-
tries = 0;
|
410
|
-
old = m->lock;
|
411
|
-
continue;
|
412
|
-
}
|
413
|
-
|
414
|
-
ngx_log_debug2(NGX_LOG_DEBUG_MUTEX, m->log, 0,
|
415
|
-
"mutex %p lock:%XD", m, m->lock);
|
416
|
-
|
417
|
-
/*
|
418
|
-
* The mutex is locked so we increase a number
|
419
|
-
* of the threads that are waiting on the mutex
|
420
|
-
*/
|
421
|
-
|
422
|
-
lock = old + 1;
|
423
|
-
|
424
|
-
if ((lock & ~NGX_MUTEX_LOCK_BUSY) > nthreads) {
|
425
|
-
ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
|
426
|
-
"%D threads wait for mutex %p, "
|
427
|
-
"while only %ui threads are available",
|
428
|
-
lock & ~NGX_MUTEX_LOCK_BUSY, m, nthreads);
|
429
|
-
ngx_abort();
|
430
|
-
}
|
431
|
-
|
432
|
-
if (ngx_atomic_cmp_set(&m->lock, old, lock)) {
|
433
|
-
|
434
|
-
ngx_log_debug2(NGX_LOG_DEBUG_MUTEX, m->log, 0,
|
435
|
-
"wait mutex %p lock:%XD", m, m->lock);
|
436
|
-
|
437
|
-
/*
|
438
|
-
* The number of the waiting threads has been increased
|
439
|
-
* and we would wait on the SysV semaphore.
|
440
|
-
* A semaphore should wake up us more efficiently than
|
441
|
-
* a simple sched_yield() or usleep().
|
442
|
-
*/
|
443
|
-
|
444
|
-
op.sem_num = 0;
|
445
|
-
op.sem_op = -1;
|
446
|
-
op.sem_flg = 0;
|
447
|
-
|
448
|
-
if (semop(m->semid, &op, 1) == -1) {
|
449
|
-
ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
|
450
|
-
"semop() failed while waiting on mutex %p", m);
|
451
|
-
ngx_abort();
|
452
|
-
}
|
453
|
-
|
454
|
-
ngx_log_debug2(NGX_LOG_DEBUG_MUTEX, m->log, 0,
|
455
|
-
"mutex waked up %p lock:%XD", m, m->lock);
|
456
|
-
|
457
|
-
tries = 0;
|
458
|
-
old = m->lock;
|
459
|
-
continue;
|
460
|
-
}
|
461
|
-
|
462
|
-
old = m->lock;
|
463
|
-
|
464
|
-
} else {
|
465
|
-
lock = old | NGX_MUTEX_LOCK_BUSY;
|
466
|
-
|
467
|
-
if (ngx_atomic_cmp_set(&m->lock, old, lock)) {
|
468
|
-
|
469
|
-
/* we locked the mutex */
|
470
|
-
|
471
|
-
break;
|
472
|
-
}
|
473
|
-
|
474
|
-
old = m->lock;
|
475
|
-
}
|
476
|
-
|
477
|
-
if (tries++ > 1000) {
|
478
|
-
|
479
|
-
ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0,
|
480
|
-
"mutex %p is contested", m);
|
481
|
-
|
482
|
-
/* the mutex is probably contested so we are giving up now */
|
483
|
-
|
484
|
-
sched_yield();
|
485
|
-
|
486
|
-
tries = 0;
|
487
|
-
old = m->lock;
|
488
|
-
}
|
489
|
-
}
|
490
|
-
|
491
|
-
ngx_log_debug2(NGX_LOG_DEBUG_MUTEX, m->log, 0,
|
492
|
-
"mutex %p is locked, lock:%XD", m, m->lock);
|
493
|
-
|
494
|
-
return NGX_OK;
|
495
|
-
}
|
496
|
-
|
497
|
-
|
498
|
-
void
|
499
|
-
ngx_mutex_unlock(ngx_mutex_t *m)
|
500
|
-
{
|
501
|
-
uint32_t lock, old;
|
502
|
-
struct sembuf op;
|
503
|
-
|
504
|
-
if (!ngx_threaded) {
|
505
|
-
return;
|
506
|
-
}
|
507
|
-
|
508
|
-
old = m->lock;
|
509
|
-
|
510
|
-
if (!(old & NGX_MUTEX_LOCK_BUSY)) {
|
511
|
-
ngx_log_error(NGX_LOG_ALERT, m->log, 0,
|
512
|
-
"trying to unlock the free mutex %p", m);
|
513
|
-
ngx_abort();
|
514
|
-
}
|
515
|
-
|
516
|
-
/* free the mutex */
|
517
|
-
|
518
|
-
#if 0
|
519
|
-
ngx_log_debug2(NGX_LOG_DEBUG_MUTEX, m->log, 0,
|
520
|
-
"unlock mutex %p lock:%XD", m, old);
|
521
|
-
#endif
|
522
|
-
|
523
|
-
for ( ;; ) {
|
524
|
-
lock = old & ~NGX_MUTEX_LOCK_BUSY;
|
525
|
-
|
526
|
-
if (ngx_atomic_cmp_set(&m->lock, old, lock)) {
|
527
|
-
break;
|
528
|
-
}
|
529
|
-
|
530
|
-
old = m->lock;
|
531
|
-
}
|
532
|
-
|
533
|
-
if (m->semid == -1) {
|
534
|
-
ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0,
|
535
|
-
"mutex %p is unlocked", m);
|
536
|
-
|
537
|
-
return;
|
538
|
-
}
|
539
|
-
|
540
|
-
/* check whether we need to wake up a waiting thread */
|
541
|
-
|
542
|
-
old = m->lock;
|
543
|
-
|
544
|
-
for ( ;; ) {
|
545
|
-
if (old & NGX_MUTEX_LOCK_BUSY) {
|
546
|
-
|
547
|
-
/* the mutex is just locked by another thread */
|
548
|
-
|
549
|
-
break;
|
550
|
-
}
|
551
|
-
|
552
|
-
if (old == 0) {
|
553
|
-
break;
|
554
|
-
}
|
555
|
-
|
556
|
-
/* there are the waiting threads */
|
557
|
-
|
558
|
-
lock = old - 1;
|
559
|
-
|
560
|
-
if (ngx_atomic_cmp_set(&m->lock, old, lock)) {
|
561
|
-
|
562
|
-
/* wake up the thread that waits on semaphore */
|
563
|
-
|
564
|
-
ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0,
|
565
|
-
"wake up mutex %p", m);
|
566
|
-
|
567
|
-
op.sem_num = 0;
|
568
|
-
op.sem_op = 1;
|
569
|
-
op.sem_flg = 0;
|
570
|
-
|
571
|
-
if (semop(m->semid, &op, 1) == -1) {
|
572
|
-
ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
|
573
|
-
"semop() failed while waking up on mutex %p", m);
|
574
|
-
ngx_abort();
|
575
|
-
}
|
576
|
-
|
577
|
-
break;
|
578
|
-
}
|
579
|
-
|
580
|
-
old = m->lock;
|
581
|
-
}
|
582
|
-
|
583
|
-
ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0,
|
584
|
-
"mutex %p is unlocked", m);
|
585
|
-
|
586
|
-
return;
|
587
|
-
}
|
588
|
-
|
589
|
-
|
590
|
-
ngx_cond_t *
|
591
|
-
ngx_cond_init(ngx_log_t *log)
|
592
|
-
{
|
593
|
-
ngx_cond_t *cv;
|
594
|
-
|
595
|
-
cv = ngx_alloc(sizeof(ngx_cond_t), log);
|
596
|
-
if (cv == NULL) {
|
597
|
-
return NULL;
|
598
|
-
}
|
599
|
-
|
600
|
-
cv->signo = NGX_CV_SIGNAL;
|
601
|
-
cv->tid = -1;
|
602
|
-
cv->log = log;
|
603
|
-
cv->kq = -1;
|
604
|
-
|
605
|
-
return cv;
|
606
|
-
}
|
607
|
-
|
608
|
-
|
609
|
-
void
|
610
|
-
ngx_cond_destroy(ngx_cond_t *cv)
|
611
|
-
{
|
612
|
-
if (close(cv->kq) == -1) {
|
613
|
-
ngx_log_error(NGX_LOG_ALERT, cv->log, ngx_errno,
|
614
|
-
"kqueue close() failed");
|
615
|
-
}
|
616
|
-
|
617
|
-
ngx_free(cv);
|
618
|
-
}
|
619
|
-
|
620
|
-
|
621
|
-
ngx_int_t
|
622
|
-
ngx_cond_wait(ngx_cond_t *cv, ngx_mutex_t *m)
|
623
|
-
{
|
624
|
-
int n;
|
625
|
-
ngx_err_t err;
|
626
|
-
struct kevent kev;
|
627
|
-
struct timespec ts;
|
628
|
-
|
629
|
-
if (cv->kq == -1) {
|
630
|
-
|
631
|
-
/*
|
632
|
-
* We have to add the EVFILT_SIGNAL filter in the rfork()ed thread.
|
633
|
-
* Otherwise the thread would not get a signal event.
|
634
|
-
*
|
635
|
-
* However, we have not to open the kqueue in the thread,
|
636
|
-
* it is simply handy do it together.
|
637
|
-
*/
|
638
|
-
|
639
|
-
cv->kq = kqueue();
|
640
|
-
if (cv->kq == -1) {
|
641
|
-
ngx_log_error(NGX_LOG_ALERT, cv->log, ngx_errno, "kqueue() failed");
|
642
|
-
return NGX_ERROR;
|
643
|
-
}
|
644
|
-
|
645
|
-
ngx_log_debug2(NGX_LOG_DEBUG_CORE, cv->log, 0,
|
646
|
-
"cv kq:%d signo:%d", cv->kq, cv->signo);
|
647
|
-
|
648
|
-
kev.ident = cv->signo;
|
649
|
-
kev.filter = EVFILT_SIGNAL;
|
650
|
-
kev.flags = EV_ADD;
|
651
|
-
kev.fflags = 0;
|
652
|
-
kev.data = 0;
|
653
|
-
kev.udata = NULL;
|
654
|
-
|
655
|
-
ts.tv_sec = 0;
|
656
|
-
ts.tv_nsec = 0;
|
657
|
-
|
658
|
-
if (kevent(cv->kq, &kev, 1, NULL, 0, &ts) == -1) {
|
659
|
-
ngx_log_error(NGX_LOG_ALERT, cv->log, ngx_errno, "kevent() failed");
|
660
|
-
return NGX_ERROR;
|
661
|
-
}
|
662
|
-
|
663
|
-
cv->tid = ngx_thread_self();
|
664
|
-
}
|
665
|
-
|
666
|
-
ngx_mutex_unlock(m);
|
667
|
-
|
668
|
-
ngx_log_debug3(NGX_LOG_DEBUG_CORE, cv->log, 0,
|
669
|
-
"cv %p wait, kq:%d, signo:%d", cv, cv->kq, cv->signo);
|
670
|
-
|
671
|
-
for ( ;; ) {
|
672
|
-
n = kevent(cv->kq, NULL, 0, &kev, 1, NULL);
|
673
|
-
|
674
|
-
ngx_log_debug2(NGX_LOG_DEBUG_CORE, cv->log, 0,
|
675
|
-
"cv %p kevent: %d", cv, n);
|
676
|
-
|
677
|
-
if (n == -1) {
|
678
|
-
err = ngx_errno;
|
679
|
-
ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
|
680
|
-
cv->log, ngx_errno,
|
681
|
-
"kevent() failed while waiting condition variable %p",
|
682
|
-
cv);
|
683
|
-
|
684
|
-
if (err == NGX_EINTR) {
|
685
|
-
break;
|
686
|
-
}
|
687
|
-
|
688
|
-
return NGX_ERROR;
|
689
|
-
}
|
690
|
-
|
691
|
-
if (n == 0) {
|
692
|
-
ngx_log_error(NGX_LOG_ALERT, cv->log, 0,
|
693
|
-
"kevent() returned no events "
|
694
|
-
"while waiting condition variable %p",
|
695
|
-
cv);
|
696
|
-
continue;
|
697
|
-
}
|
698
|
-
|
699
|
-
if (kev.filter != EVFILT_SIGNAL) {
|
700
|
-
ngx_log_error(NGX_LOG_ALERT, cv->log, 0,
|
701
|
-
"kevent() returned unexpected events: %d "
|
702
|
-
"while waiting condition variable %p",
|
703
|
-
kev.filter, cv);
|
704
|
-
continue;
|
705
|
-
}
|
706
|
-
|
707
|
-
if (kev.ident != (uintptr_t) cv->signo) {
|
708
|
-
ngx_log_error(NGX_LOG_ALERT, cv->log, 0,
|
709
|
-
"kevent() returned unexpected signal: %d ",
|
710
|
-
"while waiting condition variable %p",
|
711
|
-
kev.ident, cv);
|
712
|
-
continue;
|
713
|
-
}
|
714
|
-
|
715
|
-
break;
|
716
|
-
}
|
717
|
-
|
718
|
-
ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p is waked up", cv);
|
719
|
-
|
720
|
-
ngx_mutex_lock(m);
|
721
|
-
|
722
|
-
return NGX_OK;
|
723
|
-
}
|
724
|
-
|
725
|
-
|
726
|
-
ngx_int_t
|
727
|
-
ngx_cond_signal(ngx_cond_t *cv)
|
728
|
-
{
|
729
|
-
ngx_err_t err;
|
730
|
-
|
731
|
-
ngx_log_debug3(NGX_LOG_DEBUG_CORE, cv->log, 0,
|
732
|
-
"cv %p to signal %P %d",
|
733
|
-
cv, cv->tid, cv->signo);
|
734
|
-
|
735
|
-
if (cv->tid == -1) {
|
736
|
-
return NGX_OK;
|
737
|
-
}
|
738
|
-
|
739
|
-
if (kill(cv->tid, cv->signo) == -1) {
|
740
|
-
|
741
|
-
err = ngx_errno;
|
742
|
-
|
743
|
-
ngx_log_error(NGX_LOG_ALERT, cv->log, err,
|
744
|
-
"kill() failed while signaling condition variable %p", cv);
|
745
|
-
|
746
|
-
if (err == NGX_ESRCH) {
|
747
|
-
cv->tid = -1;
|
748
|
-
}
|
749
|
-
|
750
|
-
return NGX_ERROR;
|
751
|
-
}
|
752
|
-
|
753
|
-
ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p is signaled", cv);
|
754
|
-
|
755
|
-
return NGX_OK;
|
756
|
-
}
|