Mercurial > hg > nginx
comparison src/http/modules/ngx_http_limit_req_module.c @ 3780:d94d7104f598
change order of limit_req lookup result processing
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 14 Oct 2010 09:20:01 +0000 |
parents | 57aecfdcac3d |
children | 7697412a0921 97995d63aa36 |
comparison
equal
deleted
inserted
replaced
3779:57aecfdcac3d | 3780:d94d7104f598 |
---|---|
189 rc = ngx_http_limit_req_lookup(lrcf, hash, vv->data, len, &excess); | 189 rc = ngx_http_limit_req_lookup(lrcf, hash, vv->data, len, &excess); |
190 | 190 |
191 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 191 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
192 "limit_req: %i %ui.%03ui", rc, excess / 1000, excess % 1000); | 192 "limit_req: %i %ui.%03ui", rc, excess / 1000, excess % 1000); |
193 | 193 |
194 if (rc == NGX_DECLINED) { | |
195 | |
196 n = offsetof(ngx_rbtree_node_t, color) | |
197 + offsetof(ngx_http_limit_req_node_t, data) | |
198 + len; | |
199 | |
200 node = ngx_slab_alloc_locked(ctx->shpool, n); | |
201 if (node == NULL) { | |
202 | |
203 ngx_http_limit_req_expire(ctx, 0); | |
204 | |
205 node = ngx_slab_alloc_locked(ctx->shpool, n); | |
206 if (node == NULL) { | |
207 ngx_shmtx_unlock(&ctx->shpool->mutex); | |
208 return NGX_HTTP_SERVICE_UNAVAILABLE; | |
209 } | |
210 } | |
211 | |
212 lr = (ngx_http_limit_req_node_t *) &node->color; | |
213 | |
214 node->key = hash; | |
215 lr->len = (u_char) len; | |
216 | |
217 tp = ngx_timeofday(); | |
218 lr->last = (ngx_msec_t) (tp->sec * 1000 + tp->msec); | |
219 | |
220 lr->excess = 0; | |
221 ngx_memcpy(lr->data, vv->data, len); | |
222 | |
223 ngx_rbtree_insert(&ctx->sh->rbtree, node); | |
224 | |
225 ngx_queue_insert_head(&ctx->sh->queue, &lr->queue); | |
226 | |
227 ngx_shmtx_unlock(&ctx->shpool->mutex); | |
228 | |
229 return NGX_DECLINED; | |
230 } | |
231 | |
232 ngx_shmtx_unlock(&ctx->shpool->mutex); | |
233 | |
234 if (rc == NGX_OK) { | |
235 return NGX_DECLINED; | |
236 } | |
237 | |
194 if (rc == NGX_BUSY) { | 238 if (rc == NGX_BUSY) { |
195 ngx_shmtx_unlock(&ctx->shpool->mutex); | |
196 | |
197 ngx_log_error(lrcf->limit_log_level, r->connection->log, 0, | 239 ngx_log_error(lrcf->limit_log_level, r->connection->log, 0, |
198 "limiting requests, excess: %ui.%03ui by zone \"%V\"", | 240 "limiting requests, excess: %ui.%03ui by zone \"%V\"", |
199 excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name); | 241 excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name); |
200 | 242 |
201 return NGX_HTTP_SERVICE_UNAVAILABLE; | 243 return NGX_HTTP_SERVICE_UNAVAILABLE; |
202 } | 244 } |
203 | 245 |
204 if (rc == NGX_AGAIN) { | 246 /* rc == NGX_AGAIN */ |
205 ngx_shmtx_unlock(&ctx->shpool->mutex); | 247 |
206 | 248 if (lrcf->nodelay) { |
207 if (lrcf->nodelay) { | 249 return NGX_DECLINED; |
208 return NGX_DECLINED; | 250 } |
209 } | 251 |
210 | 252 ngx_log_error(lrcf->delay_log_level, r->connection->log, 0, |
211 ngx_log_error(lrcf->delay_log_level, r->connection->log, 0, | 253 "delaying request, excess: %ui.%03ui, by zone \"%V\"", |
212 "delaying request, excess: %ui.%03ui, by zone \"%V\"", | 254 excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name); |
213 excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name); | 255 |
214 | 256 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { |
215 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { | 257 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
216 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 258 } |
217 } | 259 |
218 | 260 r->read_event_handler = ngx_http_test_reading; |
219 r->read_event_handler = ngx_http_test_reading; | 261 r->write_event_handler = ngx_http_limit_req_delay; |
220 r->write_event_handler = ngx_http_limit_req_delay; | 262 ngx_add_timer(r->connection->write, |
221 ngx_add_timer(r->connection->write, | 263 (ngx_msec_t) excess * 1000 / ctx->rate); |
222 (ngx_msec_t) excess * 1000 / ctx->rate); | 264 |
223 | 265 return NGX_AGAIN; |
224 return NGX_AGAIN; | |
225 } | |
226 | |
227 if (rc == NGX_OK) { | |
228 goto done; | |
229 } | |
230 | |
231 /* rc == NGX_DECLINED */ | |
232 | |
233 n = offsetof(ngx_rbtree_node_t, color) | |
234 + offsetof(ngx_http_limit_req_node_t, data) | |
235 + len; | |
236 | |
237 node = ngx_slab_alloc_locked(ctx->shpool, n); | |
238 if (node == NULL) { | |
239 | |
240 ngx_http_limit_req_expire(ctx, 0); | |
241 | |
242 node = ngx_slab_alloc_locked(ctx->shpool, n); | |
243 if (node == NULL) { | |
244 ngx_shmtx_unlock(&ctx->shpool->mutex); | |
245 return NGX_HTTP_SERVICE_UNAVAILABLE; | |
246 } | |
247 } | |
248 | |
249 lr = (ngx_http_limit_req_node_t *) &node->color; | |
250 | |
251 node->key = hash; | |
252 lr->len = (u_char) len; | |
253 | |
254 tp = ngx_timeofday(); | |
255 lr->last = (ngx_msec_t) (tp->sec * 1000 + tp->msec); | |
256 | |
257 lr->excess = 0; | |
258 ngx_memcpy(lr->data, vv->data, len); | |
259 | |
260 ngx_rbtree_insert(&ctx->sh->rbtree, node); | |
261 | |
262 ngx_queue_insert_head(&ctx->sh->queue, &lr->queue); | |
263 | |
264 done: | |
265 | |
266 ngx_shmtx_unlock(&ctx->shpool->mutex); | |
267 | |
268 return NGX_DECLINED; | |
269 } | 266 } |
270 | 267 |
271 | 268 |
272 static void | 269 static void |
273 ngx_http_limit_req_delay(ngx_http_request_t *r) | 270 ngx_http_limit_req_delay(ngx_http_request_t *r) |