Mercurial > hg > nginx
comparison src/http/modules/ngx_http_limit_zone_module.c @ 1026:38be15c1379a
fix duplicate rbtree keys case
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 12 Jan 2007 20:38:17 +0000 |
parents | 11ffb8e4753f |
children | ce08bc4cb97b |
comparison
equal
deleted
inserted
replaced
1025:f88651afad40 | 1026:38be15c1379a |
---|---|
102 static ngx_int_t | 102 static ngx_int_t |
103 ngx_http_limit_zone_handler(ngx_http_request_t *r) | 103 ngx_http_limit_zone_handler(ngx_http_request_t *r) |
104 { | 104 { |
105 size_t len, n; | 105 size_t len, n; |
106 uint32_t hash; | 106 uint32_t hash; |
107 ngx_int_t rc; | |
107 ngx_slab_pool_t *shpool; | 108 ngx_slab_pool_t *shpool; |
108 ngx_rbtree_node_t *node, *sentinel; | 109 ngx_rbtree_node_t *node, *sentinel; |
109 ngx_pool_cleanup_t *cln; | 110 ngx_pool_cleanup_t *cln; |
110 ngx_http_variable_value_t *vv; | 111 ngx_http_variable_value_t *vv; |
111 ngx_http_limit_zone_ctx_t *ctx; | 112 ngx_http_limit_zone_ctx_t *ctx; |
176 /* hash == node->key */ | 177 /* hash == node->key */ |
177 | 178 |
178 do { | 179 do { |
179 lz = (ngx_http_limit_zone_node_t *) &node->color; | 180 lz = (ngx_http_limit_zone_node_t *) &node->color; |
180 | 181 |
181 if (len == (size_t) lz->len | 182 rc = ngx_strn2cmp(lz->data, vv->data, (size_t) lz->len, len); |
182 && ngx_strncmp(lz->data, vv->data, len) == 0) | 183 |
183 { | 184 if (rc == 0) { |
184 if ((ngx_uint_t) lz->conn < lzcf->conn) { | 185 if ((ngx_uint_t) lz->conn < lzcf->conn) { |
185 lz->conn++; | 186 lz->conn++; |
186 goto done; | 187 goto done; |
187 } | 188 } |
188 | 189 |
189 ngx_shmtx_unlock(&shpool->mutex); | 190 ngx_shmtx_unlock(&shpool->mutex); |
190 | 191 |
191 return NGX_HTTP_SERVICE_UNAVAILABLE; | 192 return NGX_HTTP_SERVICE_UNAVAILABLE; |
192 } | 193 } |
193 | 194 |
194 node = node->right; | 195 node = (rc < 0) ? node->left : node->right; |
195 | 196 |
196 } while (node != sentinel && hash == node->key); | 197 } while (node != sentinel && hash == node->key); |
197 | 198 |
198 break; | 199 break; |
199 } | 200 } |
229 | 230 |
230 lzcln->shm_zone = lzcf->shm_zone; | 231 lzcln->shm_zone = lzcf->shm_zone; |
231 lzcln->node = node; | 232 lzcln->node = node; |
232 | 233 |
233 return NGX_DECLINED; | 234 return NGX_DECLINED; |
235 } | |
236 | |
237 | |
238 static void | |
239 ngx_http_limit_zone_rbtree_insert_value(ngx_rbtree_node_t *temp, | |
240 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) | |
241 { | |
242 ngx_http_limit_zone_node_t *lzn, *lznt; | |
243 | |
244 for ( ;; ) { | |
245 | |
246 if (node->key < temp->key) { | |
247 | |
248 if (temp->left == sentinel) { | |
249 temp->left = node; | |
250 break; | |
251 } | |
252 | |
253 temp = temp->left; | |
254 | |
255 } else if (node->key > temp->key) { | |
256 | |
257 if (temp->right == sentinel) { | |
258 temp->right = node; | |
259 break; | |
260 } | |
261 | |
262 temp = temp->right; | |
263 | |
264 } else { /* node->key == temp->key */ | |
265 | |
266 lzn = (ngx_http_limit_zone_node_t *) &node->color; | |
267 lznt = (ngx_http_limit_zone_node_t *) &temp->color; | |
268 | |
269 if (ngx_strn2cmp(lzn->data, lznt->data, lzn->len, lznt->len) < 0) { | |
270 | |
271 if (temp->left == sentinel) { | |
272 temp->left = node; | |
273 break; | |
274 } | |
275 | |
276 temp = temp->left; | |
277 | |
278 } else { | |
279 | |
280 if (temp->right == sentinel) { | |
281 temp->right = node; | |
282 break; | |
283 } | |
284 | |
285 temp = temp->right; | |
286 } | |
287 } | |
288 } | |
289 | |
290 node->parent = temp; | |
291 node->left = sentinel; | |
292 node->right = sentinel; | |
293 ngx_rbt_red(node); | |
234 } | 294 } |
235 | 295 |
236 | 296 |
237 static void | 297 static void |
238 ngx_http_limit_zone_cleanup(void *data) | 298 ngx_http_limit_zone_cleanup(void *data) |
304 | 364 |
305 ngx_rbtree_sentinel_init(sentinel); | 365 ngx_rbtree_sentinel_init(sentinel); |
306 | 366 |
307 ctx->rbtree->root = sentinel; | 367 ctx->rbtree->root = sentinel; |
308 ctx->rbtree->sentinel = sentinel; | 368 ctx->rbtree->sentinel = sentinel; |
309 ctx->rbtree->insert = ngx_rbtree_insert_value; | 369 ctx->rbtree->insert = ngx_http_limit_zone_rbtree_insert_value; |
310 | 370 |
311 return NGX_OK; | 371 return NGX_OK; |
312 } | 372 } |
313 | 373 |
314 | 374 |