diff options
author | Valentin Bartenev <vbart@nginx.com> | 2011-11-10 15:51:55 +0000 |
---|---|---|
committer | Valentin Bartenev <vbart@nginx.com> | 2011-11-10 15:51:55 +0000 |
commit | 54660dcf742b8907c36c9e95c0dc03f9f6108fbe (patch) | |
tree | 9b403fedfbeca3576a6eb0c00b8175b5fd780843 /src | |
parent | 2f37fbc8f9670edd0e014c74bcb6879a1a38c3e1 (diff) | |
download | nginx-54660dcf742b8907c36c9e95c0dc03f9f6108fbe.tar.gz nginx-54660dcf742b8907c36c9e95c0dc03f9f6108fbe.zip |
Limit zone: rbtree lookup moved to a separate function.
No functional changes.
Diffstat (limited to 'src')
-rw-r--r-- | src/http/modules/ngx_http_limit_zone_module.c | 124 |
1 files changed, 73 insertions, 51 deletions
diff --git a/src/http/modules/ngx_http_limit_zone_module.c b/src/http/modules/ngx_http_limit_zone_module.c index 31df316e4..3992c0c31 100644 --- a/src/http/modules/ngx_http_limit_zone_module.c +++ b/src/http/modules/ngx_http_limit_zone_module.c @@ -37,6 +37,8 @@ typedef struct { } ngx_http_limit_zone_conf_t; +static ngx_rbtree_node_t *ngx_http_limit_zone_lookup(ngx_rbtree_t *rbtree, + ngx_http_variable_value_t *vv, uint32_t hash); static void ngx_http_limit_zone_cleanup(void *data); static void *ngx_http_limit_zone_create_conf(ngx_conf_t *cf); @@ -121,9 +123,8 @@ ngx_http_limit_zone_handler(ngx_http_request_t *r) { size_t len, n; uint32_t hash; - ngx_int_t rc; ngx_slab_pool_t *shpool; - ngx_rbtree_node_t *node, *sentinel; + ngx_rbtree_node_t *node; ngx_pool_cleanup_t *cln; ngx_http_variable_value_t *vv; ngx_http_limit_zone_ctx_t *ctx; @@ -176,71 +177,47 @@ ngx_http_limit_zone_handler(ngx_http_request_t *r) ngx_shmtx_lock(&shpool->mutex); - node = ctx->rbtree->root; - sentinel = ctx->rbtree->sentinel; + node = ngx_http_limit_zone_lookup(ctx->rbtree, vv, hash); - while (node != sentinel) { + if (node == NULL) { - if (hash < node->key) { - node = node->left; - continue; - } + n = offsetof(ngx_rbtree_node_t, color) + + offsetof(ngx_http_limit_zone_node_t, data) + + len; - if (hash > node->key) { - node = node->right; - continue; + node = ngx_slab_alloc_locked(shpool, n); + if (node == NULL) { + ngx_shmtx_unlock(&shpool->mutex); + return NGX_HTTP_SERVICE_UNAVAILABLE; } - /* hash == node->key */ + lz = (ngx_http_limit_zone_node_t *) &node->color; - do { - lz = (ngx_http_limit_zone_node_t *) &node->color; + node->key = hash; + lz->len = (u_char) len; + lz->conn = 1; + ngx_memcpy(lz->data, vv->data, len); - rc = ngx_memn2cmp(vv->data, lz->data, len, (size_t) lz->len); + ngx_rbtree_insert(ctx->rbtree, node); - if (rc == 0) { - if ((ngx_uint_t) lz->conn < lzcf->conn) { - lz->conn++; - goto done; - } + } else { - ngx_shmtx_unlock(&shpool->mutex); - - ngx_log_error(lzcf->log_level, r->connection->log, 0, - "limiting connections by zone \"%V\"", - &lzcf->shm_zone->shm.name); - - return NGX_HTTP_SERVICE_UNAVAILABLE; - } + lz = (ngx_http_limit_zone_node_t *) &node->color; - node = (rc < 0) ? node->left : node->right; + if ((ngx_uint_t) lz->conn >= lzcf->conn) { - } while (node != sentinel && hash == node->key); + ngx_shmtx_unlock(&shpool->mutex); - break; - } + ngx_log_error(lzcf->log_level, r->connection->log, 0, + "limiting connections by zone \"%V\"", + &lzcf->shm_zone->shm.name); - n = offsetof(ngx_rbtree_node_t, color) - + offsetof(ngx_http_limit_zone_node_t, data) - + len; + return NGX_HTTP_SERVICE_UNAVAILABLE; + } - node = ngx_slab_alloc_locked(shpool, n); - if (node == NULL) { - ngx_shmtx_unlock(&shpool->mutex); - return NGX_HTTP_SERVICE_UNAVAILABLE; + lz->conn++; } - lz = (ngx_http_limit_zone_node_t *) &node->color; - - node->key = hash; - lz->len = (u_char) len; - lz->conn = 1; - ngx_memcpy(lz->data, vv->data, len); - - ngx_rbtree_insert(ctx->rbtree, node); - -done: - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "limit zone: %08XD %d", node->key, lz->conn); @@ -297,6 +274,51 @@ ngx_http_limit_zone_rbtree_insert_value(ngx_rbtree_node_t *temp, } +static ngx_rbtree_node_t * +ngx_http_limit_zone_lookup(ngx_rbtree_t *rbtree, ngx_http_variable_value_t *vv, + uint32_t hash) +{ + ngx_int_t rc; + ngx_rbtree_node_t *node, *sentinel; + ngx_http_limit_zone_node_t *lzn; + + node = rbtree->root; + sentinel = rbtree->sentinel; + + while (node != sentinel) { + + if (hash < node->key) { + node = node->left; + continue; + } + + if (hash > node->key) { + node = node->right; + continue; + } + + /* hash == node->key */ + + do { + lzn = (ngx_http_limit_zone_node_t *) &node->color; + + rc = ngx_memn2cmp(vv->data, lzn->data, + (size_t) vv->len, (size_t) lzn->len); + if (rc == 0) { + return node; + } + + node = (rc < 0) ? node->left : node->right; + + } while (node != sentinel && hash == node->key); + + break; + } + + return NULL; +} + + static void ngx_http_limit_zone_cleanup(void *data) { |