Mercurial > hg > nginx-vendor-current
comparison src/core/ngx_shmtx.c @ 650:4d05413aebad NGINX_1_1_9
nginx 1.1.9
*) Change: now double quotes are encoded in an "echo" SSI-command
output.
Thanks to Zaur Abasmirzoev.
*) Feature: the "valid" parameter of the "resolver" directive. By
default TTL returned by a DNS server is used.
Thanks to Kirill A. Korinskiy.
*) Bugfix: nginx might hang after a worker process abnormal termination.
*) Bugfix: a segmentation fault might occur in a worker process if SNI
was used; the bug had appeared in 1.1.2.
*) Bugfix: in the "keepalive_disable" directive; the bug had appeared in
1.1.8.
Thanks to Alexander Usov.
*) Bugfix: SIGWINCH signal did not work after first binary upgrade; the
bug had appeared in 1.1.1.
*) Bugfix: backend responses with length not matching "Content-Length"
header line are no longer cached.
*) Bugfix: in the "scgi_param" directive, if complex parameters were
used.
*) Bugfix: in the "epoll" event method.
Thanks to Yichun Zhang.
*) Bugfix: in the ngx_http_flv_module.
Thanks to Piotr Sikora.
*) Bugfix: in the ngx_http_mp4_module.
*) Bugfix: IPv6 addresses are now handled properly in a request line and
in a "Host" request header line.
*) Bugfix: "add_header" and "expires" directives did not work if a
request was proxied and response status code was 206.
*) Bugfix: nginx could not be built on FreeBSD 10.
*) Bugfix: nginx could not be built on AIX.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 28 Nov 2011 00:00:00 +0400 |
parents | d4da38525468 |
children | d0f7a625f27c |
comparison
equal
deleted
inserted
replaced
649:c5b99ec117cd | 650:4d05413aebad |
---|---|
9 | 9 |
10 | 10 |
11 #if (NGX_HAVE_ATOMIC_OPS) | 11 #if (NGX_HAVE_ATOMIC_OPS) |
12 | 12 |
13 | 13 |
14 static void ngx_shmtx_wakeup(ngx_shmtx_t *mtx); | |
15 | |
16 | |
14 ngx_int_t | 17 ngx_int_t |
15 ngx_shmtx_create(ngx_shmtx_t *mtx, void *addr, u_char *name) | 18 ngx_shmtx_create(ngx_shmtx_t *mtx, ngx_shmtx_sh_t *addr, u_char *name) |
16 { | 19 { |
17 mtx->lock = addr; | 20 mtx->lock = &addr->lock; |
18 | 21 |
19 if (mtx->spin == (ngx_uint_t) -1) { | 22 if (mtx->spin == (ngx_uint_t) -1) { |
20 return NGX_OK; | 23 return NGX_OK; |
21 } | 24 } |
22 | 25 |
23 mtx->spin = 2048; | 26 mtx->spin = 2048; |
24 | 27 |
25 #if (NGX_HAVE_POSIX_SEM) | 28 #if (NGX_HAVE_POSIX_SEM) |
29 | |
30 mtx->wait = &addr->wait; | |
26 | 31 |
27 if (sem_init(&mtx->sem, 1, 0) == -1) { | 32 if (sem_init(&mtx->sem, 1, 0) == -1) { |
28 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, | 33 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, |
29 "sem_init() failed"); | 34 "sem_init() failed"); |
30 } else { | 35 } else { |
54 | 59 |
55 | 60 |
56 ngx_uint_t | 61 ngx_uint_t |
57 ngx_shmtx_trylock(ngx_shmtx_t *mtx) | 62 ngx_shmtx_trylock(ngx_shmtx_t *mtx) |
58 { | 63 { |
59 ngx_atomic_uint_t val; | 64 return (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid)); |
60 | |
61 val = *mtx->lock; | |
62 | |
63 return ((val & 0x80000000) == 0 | |
64 && ngx_atomic_cmp_set(mtx->lock, val, val | 0x80000000)); | |
65 } | 65 } |
66 | 66 |
67 | 67 |
68 void | 68 void |
69 ngx_shmtx_lock(ngx_shmtx_t *mtx) | 69 ngx_shmtx_lock(ngx_shmtx_t *mtx) |
70 { | 70 { |
71 ngx_uint_t i, n; | 71 ngx_uint_t i, n; |
72 ngx_atomic_uint_t val; | |
73 | 72 |
74 ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "shmtx lock"); | 73 ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "shmtx lock"); |
75 | 74 |
76 for ( ;; ) { | 75 for ( ;; ) { |
77 | 76 |
78 val = *mtx->lock; | 77 if (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid)) { |
79 | |
80 if ((val & 0x80000000) == 0 | |
81 && ngx_atomic_cmp_set(mtx->lock, val, val | 0x80000000)) | |
82 { | |
83 return; | 78 return; |
84 } | 79 } |
85 | 80 |
86 if (ngx_ncpu > 1) { | 81 if (ngx_ncpu > 1) { |
87 | 82 |
89 | 84 |
90 for (i = 0; i < n; i++) { | 85 for (i = 0; i < n; i++) { |
91 ngx_cpu_pause(); | 86 ngx_cpu_pause(); |
92 } | 87 } |
93 | 88 |
94 val = *mtx->lock; | 89 if (*mtx->lock == 0 |
95 | 90 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid)) |
96 if ((val & 0x80000000) == 0 | |
97 && ngx_atomic_cmp_set(mtx->lock, val, val | 0x80000000)) | |
98 { | 91 { |
99 return; | 92 return; |
100 } | 93 } |
101 } | 94 } |
102 } | 95 } |
103 | 96 |
104 #if (NGX_HAVE_POSIX_SEM) | 97 #if (NGX_HAVE_POSIX_SEM) |
105 | 98 |
106 if (mtx->semaphore) { | 99 if (mtx->semaphore) { |
107 val = *mtx->lock; | 100 (void) ngx_atomic_fetch_add(mtx->wait, 1); |
108 | 101 |
109 if ((val & 0x80000000) | 102 if (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid)) { |
110 && ngx_atomic_cmp_set(mtx->lock, val, val + 1)) | 103 return; |
111 { | 104 } |
112 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, | 105 |
113 "shmtx wait %XA", val); | 106 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, |
114 | 107 "shmtx wait %uA", *mtx->wait); |
115 while (sem_wait(&mtx->sem) == -1) { | 108 |
116 ngx_err_t err; | 109 while (sem_wait(&mtx->sem) == -1) { |
117 | 110 ngx_err_t err; |
118 err = ngx_errno; | 111 |
119 | 112 err = ngx_errno; |
120 if (err != NGX_EINTR) { | 113 |
121 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err, | 114 if (err != NGX_EINTR) { |
122 "sem_wait() failed while waiting on shmtx"); | 115 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err, |
123 break; | 116 "sem_wait() failed while waiting on shmtx"); |
124 } | 117 break; |
125 } | 118 } |
126 | 119 |
127 ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, | 120 ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, |
128 "shmtx awoke"); | 121 "shmtx awoke"); |
129 } | 122 } |
139 | 132 |
140 | 133 |
141 void | 134 void |
142 ngx_shmtx_unlock(ngx_shmtx_t *mtx) | 135 ngx_shmtx_unlock(ngx_shmtx_t *mtx) |
143 { | 136 { |
144 ngx_atomic_uint_t val, old, wait; | |
145 | |
146 if (mtx->spin != (ngx_uint_t) -1) { | 137 if (mtx->spin != (ngx_uint_t) -1) { |
147 ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "shmtx unlock"); | 138 ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "shmtx unlock"); |
148 } | 139 } |
149 | 140 |
141 if (ngx_atomic_cmp_set(mtx->lock, ngx_pid, 0)) { | |
142 ngx_shmtx_wakeup(mtx); | |
143 } | |
144 } | |
145 | |
146 | |
147 ngx_uint_t | |
148 ngx_shmtx_force_unlock(ngx_shmtx_t *mtx, ngx_pid_t pid) | |
149 { | |
150 ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, | |
151 "shmtx forced unlock"); | |
152 | |
153 if (ngx_atomic_cmp_set(mtx->lock, pid, 0)) { | |
154 ngx_shmtx_wakeup(mtx); | |
155 return 1; | |
156 } | |
157 | |
158 return 0; | |
159 } | |
160 | |
161 | |
162 static void | |
163 ngx_shmtx_wakeup(ngx_shmtx_t *mtx) | |
164 { | |
165 #if (NGX_HAVE_POSIX_SEM) | |
166 ngx_atomic_uint_t wait; | |
167 | |
168 if (!mtx->semaphore) { | |
169 return; | |
170 } | |
171 | |
150 for ( ;; ) { | 172 for ( ;; ) { |
151 | 173 |
152 old = *mtx->lock; | 174 wait = *mtx->wait; |
153 wait = old & 0x7fffffff; | 175 |
154 val = wait ? wait - 1 : 0; | 176 if (wait == 0) { |
155 | 177 return; |
156 if (ngx_atomic_cmp_set(mtx->lock, old, val)) { | 178 } |
179 | |
180 if (ngx_atomic_cmp_set(mtx->wait, wait, wait - 1)) { | |
157 break; | 181 break; |
158 } | 182 } |
159 } | 183 } |
160 | 184 |
161 #if (NGX_HAVE_POSIX_SEM) | |
162 | |
163 if (wait == 0 || !mtx->semaphore) { | |
164 return; | |
165 } | |
166 | |
167 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, | 185 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, |
168 "shmtx wake %XA", old); | 186 "shmtx wake %uA", wait); |
169 | 187 |
170 if (sem_post(&mtx->sem) == -1) { | 188 if (sem_post(&mtx->sem) == -1) { |
171 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, | 189 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, |
172 "sem_post() failed while wake shmtx"); | 190 "sem_post() failed while wake shmtx"); |
173 } | 191 } |
178 | 196 |
179 #else | 197 #else |
180 | 198 |
181 | 199 |
182 ngx_int_t | 200 ngx_int_t |
183 ngx_shmtx_create(ngx_shmtx_t *mtx, void *addr, u_char *name) | 201 ngx_shmtx_create(ngx_shmtx_t *mtx, ngx_shmtx_sh_t *addr, u_char *name) |
184 { | 202 { |
185 if (mtx->name) { | 203 if (mtx->name) { |
186 | 204 |
187 if (ngx_strcmp(name, mtx->name) == 0) { | 205 if (ngx_strcmp(name, mtx->name) == 0) { |
188 mtx->name = name; | 206 mtx->name = name; |
278 } | 296 } |
279 | 297 |
280 ngx_log_abort(err, ngx_unlock_fd_n " %s failed", mtx->name); | 298 ngx_log_abort(err, ngx_unlock_fd_n " %s failed", mtx->name); |
281 } | 299 } |
282 | 300 |
283 #endif | 301 |
302 ngx_uint_t | |
303 ngx_shmtx_force_unlock(ngx_shmtx_t *mtx, ngx_pid_t pid) | |
304 { | |
305 return 0; | |
306 } | |
307 | |
308 #endif |