Klaus Demo nginx / 0ffc4c3
Merge of r4498: Fix of rbtree lookup on hash collisions. Previous code incorrectly assumed that nodes with identical keys are linked together. This might not be true after tree rebalance. Patch by Lanshun Zhou. Maxim Dounin 8 years ago
6 changed file(s) with 131 addition(s) and 166 deletion(s). Raw diff Collapse all Expand all
836836
837837 /* hash == node->key */
838838
839 do {
840 file = (ngx_cached_open_file_t *) node;
841
842 rc = ngx_strcmp(name->data, file->name);
843
844 if (rc == 0) {
845 return file;
846 }
847
848 node = (rc < 0) ? node->left : node->right;
849
850 } while (node != sentinel && hash == node->key);
851
852 break;
839 file = (ngx_cached_open_file_t *) node;
840
841 rc = ngx_strcmp(name->data, file->name);
842
843 if (rc == 0) {
844 return file;
845 }
846
847 node = (rc < 0) ? node->left : node->right;
853848 }
854849
855850 return NULL;
16251625
16261626 /* hash == node->key */
16271627
1628 do {
1629 rn = (ngx_resolver_node_t *) node;
1630
1631 rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen);
1632
1633 if (rc == 0) {
1634 return rn;
1635 }
1636
1637 node = (rc < 0) ? node->left : node->right;
1638
1639 } while (node != sentinel && hash == node->key);
1640
1641 break;
1628 rn = (ngx_resolver_node_t *) node;
1629
1630 rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen);
1631
1632 if (rc == 0) {
1633 return rn;
1634 }
1635
1636 node = (rc < 0) ? node->left : node->right;
16421637 }
16431638
16441639 /* not found */
18001800
18011801 /* hash == node->key */
18021802
1803 do {
1804 sess_id = (ngx_ssl_sess_id_t *) node;
1805
1806 rc = ngx_memn2cmp(id, sess_id->id,
1807 (size_t) len, (size_t) node->data);
1808 if (rc == 0) {
1809
1810 if (sess_id->expire > ngx_time()) {
1811 ngx_memcpy(buf, sess_id->session, sess_id->len);
1812
1813 ngx_shmtx_unlock(&shpool->mutex);
1814
1815 p = buf;
1816 sess = d2i_SSL_SESSION(NULL, &p, sess_id->len);
1817
1818 return sess;
1819 }
1820
1821 ngx_queue_remove(&sess_id->queue);
1822
1823 ngx_rbtree_delete(&cache->session_rbtree, node);
1824
1825 ngx_slab_free_locked(shpool, sess_id->session);
1803 sess_id = (ngx_ssl_sess_id_t *) node;
1804
1805 rc = ngx_memn2cmp(id, sess_id->id, (size_t) len, (size_t) node->data);
1806
1807 if (rc == 0) {
1808
1809 if (sess_id->expire > ngx_time()) {
1810 ngx_memcpy(buf, sess_id->session, sess_id->len);
1811
1812 ngx_shmtx_unlock(&shpool->mutex);
1813
1814 p = buf;
1815 sess = d2i_SSL_SESSION(NULL, &p, sess_id->len);
1816
1817 return sess;
1818 }
1819
1820 ngx_queue_remove(&sess_id->queue);
1821
1822 ngx_rbtree_delete(&cache->session_rbtree, node);
1823
1824 ngx_slab_free_locked(shpool, sess_id->session);
18261825 #if (NGX_PTR_SIZE == 4)
1827 ngx_slab_free_locked(shpool, sess_id->id);
1826 ngx_slab_free_locked(shpool, sess_id->id);
18281827 #endif
1829 ngx_slab_free_locked(shpool, sess_id);
1830
1831 sess = NULL;
1832
1833 goto done;
1834 }
1835
1836 node = (rc < 0) ? node->left : node->right;
1837
1838 } while (node != sentinel && hash == node->key);
1839
1840 break;
1828 ngx_slab_free_locked(shpool, sess_id);
1829
1830 sess = NULL;
1831
1832 goto done;
1833 }
1834
1835 node = (rc < 0) ? node->left : node->right;
18411836 }
18421837
18431838 done:
19071902
19081903 /* hash == node->key */
19091904
1910 do {
1911 sess_id = (ngx_ssl_sess_id_t *) node;
1912
1913 rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data);
1914
1915 if (rc == 0) {
1916
1917 ngx_queue_remove(&sess_id->queue);
1918
1919 ngx_rbtree_delete(&cache->session_rbtree, node);
1920
1921 ngx_slab_free_locked(shpool, sess_id->session);
1905 sess_id = (ngx_ssl_sess_id_t *) node;
1906
1907 rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data);
1908
1909 if (rc == 0) {
1910
1911 ngx_queue_remove(&sess_id->queue);
1912
1913 ngx_rbtree_delete(&cache->session_rbtree, node);
1914
1915 ngx_slab_free_locked(shpool, sess_id->session);
19221916 #if (NGX_PTR_SIZE == 4)
1923 ngx_slab_free_locked(shpool, sess_id->id);
1917 ngx_slab_free_locked(shpool, sess_id->id);
19241918 #endif
1925 ngx_slab_free_locked(shpool, sess_id);
1926
1927 goto done;
1928 }
1929
1930 node = (rc < 0) ? node->left : node->right;
1931
1932 } while (node != sentinel && hash == node->key);
1933
1934 break;
1919 ngx_slab_free_locked(shpool, sess_id);
1920
1921 goto done;
1922 }
1923
1924 node = (rc < 0) ? node->left : node->right;
19351925 }
19361926
19371927 done:
371371
372372 /* hash == node->key */
373373
374 do {
375 lr = (ngx_http_limit_req_node_t *) &node->color;
376
377 rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len);
378
379 if (rc == 0) {
380 ngx_queue_remove(&lr->queue);
381 ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
382
383 tp = ngx_timeofday();
384
385 now = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
386 ms = (ngx_msec_int_t) (now - lr->last);
387
388 excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
389
390 if (excess < 0) {
391 excess = 0;
392 }
393
394 *ep = excess;
395
396 if ((ngx_uint_t) excess > lrcf->burst) {
397 return NGX_BUSY;
398 }
399
400 lr->excess = excess;
401 lr->last = now;
402
403 if (excess) {
404 return NGX_AGAIN;
405 }
406
407 return NGX_OK;
408 }
409
410 node = (rc < 0) ? node->left : node->right;
411
412 } while (node != sentinel && hash == node->key);
413
414 break;
374 lr = (ngx_http_limit_req_node_t *) &node->color;
375
376 rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len);
377
378 if (rc == 0) {
379 ngx_queue_remove(&lr->queue);
380 ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
381
382 tp = ngx_timeofday();
383
384 now = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
385 ms = (ngx_msec_int_t) (now - lr->last);
386
387 excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
388
389 if (excess < 0) {
390 excess = 0;
391 }
392
393 *ep = excess;
394
395 if ((ngx_uint_t) excess > lrcf->burst) {
396 return NGX_BUSY;
397 }
398
399 lr->excess = excess;
400 lr->last = now;
401
402 if (excess) {
403 return NGX_AGAIN;
404 }
405
406 return NGX_OK;
407 }
408
409 node = (rc < 0) ? node->left : node->right;
415410 }
416411
417412 *ep = 0;
193193
194194 /* hash == node->key */
195195
196 do {
197 lz = (ngx_http_limit_zone_node_t *) &node->color;
198
199 rc = ngx_memn2cmp(vv->data, lz->data, len, (size_t) lz->len);
200
201 if (rc == 0) {
202 if ((ngx_uint_t) lz->conn < lzcf->conn) {
203 lz->conn++;
204 goto done;
205 }
206
207 ngx_shmtx_unlock(&shpool->mutex);
208
209 ngx_log_error(lzcf->log_level, r->connection->log, 0,
210 "limiting connections by zone \"%V\"",
211 &lzcf->shm_zone->shm.name);
212
213 return NGX_HTTP_SERVICE_UNAVAILABLE;
196 lz = (ngx_http_limit_zone_node_t *) &node->color;
197
198 rc = ngx_memn2cmp(vv->data, lz->data, len, (size_t) lz->len);
199
200 if (rc == 0) {
201 if ((ngx_uint_t) lz->conn < lzcf->conn) {
202 lz->conn++;
203 goto done;
214204 }
215205
216 node = (rc < 0) ? node->left : node->right;
217
218 } while (node != sentinel && hash == node->key);
219
220 break;
206 ngx_shmtx_unlock(&shpool->mutex);
207
208 ngx_log_error(lzcf->log_level, r->connection->log, 0,
209 "limiting connections by zone \"%V\"",
210 &lzcf->shm_zone->shm.name);
211
212 return NGX_HTTP_SERVICE_UNAVAILABLE;
213 }
214
215 node = (rc < 0) ? node->left : node->right;
221216 }
222217
223218 n = offsetof(ngx_rbtree_node_t, color)
672672
673673 /* node_key == node->key */
674674
675 do {
676 fcn = (ngx_http_file_cache_node_t *) node;
677
678 rc = ngx_memcmp(&key[sizeof(ngx_rbtree_key_t)], fcn->key,
679 NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t));
680
681 if (rc == 0) {
682 return fcn;
683 }
684
685 node = (rc < 0) ? node->left : node->right;
686
687 } while (node != sentinel && node_key == node->key);
688
689 break;
675 fcn = (ngx_http_file_cache_node_t *) node;
676
677 rc = ngx_memcmp(&key[sizeof(ngx_rbtree_key_t)], fcn->key,
678 NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t));
679
680 if (rc == 0) {
681 return fcn;
682 }
683
684 node = (rc < 0) ? node->left : node->right;
690685 }
691686
692687 /* not found */