[nginx] Upstreams: locking.

Ruslan Ermilov ru at nginx.com
Thu Apr 16 12:23:17 UTC 2015


details:   http://hg.nginx.org/nginx/rev/3264b7828f72
branches:  
changeset: 6102:3264b7828f72
user:      Ruslan Ermilov <ru at nginx.com>
date:      Tue Apr 14 19:01:23 2015 +0300
description:
Upstreams: locking.

diffstat:

 src/http/modules/ngx_http_upstream_hash_module.c       |  16 ++++++++
 src/http/modules/ngx_http_upstream_ip_hash_module.c    |  11 ++---
 src/http/modules/ngx_http_upstream_least_conn_module.c |  10 +++++
 src/http/ngx_http_upstream_round_robin.c               |  35 ++++++-----------
 src/http/ngx_http_upstream_round_robin.h               |   7 +++
 5 files changed, 50 insertions(+), 29 deletions(-)

diffs (truncated from 312 to 300 lines):

diff -r 682d8222c6b1 -r 3264b7828f72 src/http/modules/ngx_http_upstream_hash_module.c
--- a/src/http/modules/ngx_http_upstream_hash_module.c	Sat Mar 21 14:05:08 2015 +0300
+++ b/src/http/modules/ngx_http_upstream_hash_module.c	Tue Apr 14 19:01:23 2015 +0300
@@ -176,7 +176,10 @@ ngx_http_upstream_get_hash_peer(ngx_peer
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
                    "get hash peer, try: %ui", pc->tries);
 
+    ngx_http_upstream_rr_peers_wlock(hp->rrp.peers);
+
     if (hp->tries > 20 || hp->rrp.peers->single) {
+        ngx_http_upstream_rr_peers_unlock(hp->rrp.peers);
         return hp->get_rr_peer(pc, &hp->rrp);
     }
 
@@ -258,6 +261,7 @@ ngx_http_upstream_get_hash_peer(ngx_peer
     next:
 
         if (++hp->tries > 20) {
+            ngx_http_upstream_rr_peers_unlock(hp->rrp.peers);
             return hp->get_rr_peer(pc, &hp->rrp);
         }
     }
@@ -274,6 +278,8 @@ ngx_http_upstream_get_hash_peer(ngx_peer
         peer->checked = now;
     }
 
+    ngx_http_upstream_rr_peers_unlock(hp->rrp.peers);
+
     hp->rrp.tried[n] |= m;
 
     return NGX_OK;
@@ -465,8 +471,13 @@ ngx_http_upstream_init_chash_peer(ngx_ht
     hcf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_hash_module);
 
     hash = ngx_crc32_long(hp->key.data, hp->key.len);
+
+    ngx_http_upstream_rr_peers_rlock(hp->rrp.peers);
+
     hp->hash = ngx_http_upstream_find_chash_point(hcf->points, hash);
 
+    ngx_http_upstream_rr_peers_unlock(hp->rrp.peers);
+
     return NGX_OK;
 }
 
@@ -489,6 +500,8 @@ ngx_http_upstream_get_chash_peer(ngx_pee
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
                    "get consistent hash peer, try: %ui", pc->tries);
 
+    ngx_http_upstream_rr_peers_wlock(hp->rrp.peers);
+
     pc->cached = 0;
     pc->connection = NULL;
 
@@ -561,6 +574,7 @@ ngx_http_upstream_get_chash_peer(ngx_pee
         hp->tries++;
 
         if (hp->tries >= points->number) {
+            ngx_http_upstream_rr_peers_unlock(hp->rrp.peers);
             return NGX_BUSY;
         }
     }
@@ -579,6 +593,8 @@ found:
         best->checked = now;
     }
 
+    ngx_http_upstream_rr_peers_unlock(hp->rrp.peers);
+
     n = best_i / (8 * sizeof(uintptr_t));
     m = (uintptr_t) 1 << best_i % (8 * sizeof(uintptr_t));
 
diff -r 682d8222c6b1 -r 3264b7828f72 src/http/modules/ngx_http_upstream_ip_hash_module.c
--- a/src/http/modules/ngx_http_upstream_ip_hash_module.c	Sat Mar 21 14:05:08 2015 +0300
+++ b/src/http/modules/ngx_http_upstream_ip_hash_module.c	Tue Apr 14 19:01:23 2015 +0300
@@ -161,7 +161,10 @@ ngx_http_upstream_get_ip_hash_peer(ngx_p
 
     /* TODO: cached */
 
+    ngx_http_upstream_rr_peers_wlock(iphp->rrp.peers);
+
     if (iphp->tries > 20 || iphp->rrp.peers->single) {
+        ngx_http_upstream_rr_peers_unlock(iphp->rrp.peers);
         return iphp->get_rr_peer(pc, &iphp->rrp);
     }
 
@@ -212,8 +215,6 @@ ngx_http_upstream_get_ip_hash_peer(ngx_p
         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
                        "get ip hash peer, hash: %ui %04XA", p, m);
 
-        /* ngx_lock_mutex(iphp->rrp.peers->mutex); */
-
         if (peer->down) {
             goto next_try;
         }
@@ -230,14 +231,12 @@ ngx_http_upstream_get_ip_hash_peer(ngx_p
     next_try:
 
         iphp->rrp.tried[n] |= m;
-
-        /* ngx_unlock_mutex(iphp->rrp.peers->mutex); */
-
         pc->tries--;
 
     next:
 
         if (++iphp->tries > 20) {
+            ngx_http_upstream_rr_peers_unlock(iphp->rrp.peers);
             return iphp->get_rr_peer(pc, &iphp->rrp);
         }
     }
@@ -254,7 +253,7 @@ ngx_http_upstream_get_ip_hash_peer(ngx_p
         peer->checked = now;
     }
 
-    /* ngx_unlock_mutex(iphp->rrp.peers->mutex); */
+    ngx_http_upstream_rr_peers_unlock(iphp->rrp.peers);
 
     iphp->rrp.tried[n] |= m;
     iphp->hash = hash;
diff -r 682d8222c6b1 -r 3264b7828f72 src/http/modules/ngx_http_upstream_least_conn_module.c
--- a/src/http/modules/ngx_http_upstream_least_conn_module.c	Sat Mar 21 14:05:08 2015 +0300
+++ b/src/http/modules/ngx_http_upstream_least_conn_module.c	Tue Apr 14 19:01:23 2015 +0300
@@ -122,6 +122,8 @@ ngx_http_upstream_get_least_conn_peer(ng
 
     peers = rrp->peers;
 
+    ngx_http_upstream_rr_peers_wlock(peers);
+
     best = NULL;
     total = 0;
 
@@ -241,6 +243,8 @@ ngx_http_upstream_get_least_conn_peer(ng
 
     rrp->tried[n] |= m;
 
+    ngx_http_upstream_rr_peers_unlock(peers);
+
     return NGX_OK;
 
 failed:
@@ -258,11 +262,15 @@ failed:
              rrp->tried[i] = 0;
         }
 
+        ngx_http_upstream_rr_peers_unlock(peers);
+
         rc = ngx_http_upstream_get_least_conn_peer(pc, rrp);
 
         if (rc != NGX_BUSY) {
             return rc;
         }
+
+        ngx_http_upstream_rr_peers_wlock(peers);
     }
 
     /* all peers failed, mark them as live for quick recovery */
@@ -271,6 +279,8 @@ failed:
         peer->fails = 0;
     }
 
+    ngx_http_upstream_rr_peers_unlock(peers);
+
     pc->name = peers->name;
 
     return NGX_BUSY;
diff -r 682d8222c6b1 -r 3264b7828f72 src/http/ngx_http_upstream_round_robin.c
--- a/src/http/ngx_http_upstream_round_robin.c	Sat Mar 21 14:05:08 2015 +0300
+++ b/src/http/ngx_http_upstream_round_robin.c	Tue Apr 14 19:01:23 2015 +0300
@@ -432,8 +432,7 @@ ngx_http_upstream_get_round_robin_peer(n
     pc->connection = NULL;
 
     peers = rrp->peers;
-
-    /* ngx_lock_mutex(peers->mutex); */
+    ngx_http_upstream_rr_peers_wlock(peers);
 
     if (peers->single) {
         peer = peers->peer;
@@ -465,7 +464,7 @@ ngx_http_upstream_get_round_robin_peer(n
 
     peer->conns++;
 
-    /* ngx_unlock_mutex(peers->mutex); */
+    ngx_http_upstream_rr_peers_unlock(peers);
 
     return NGX_OK;
 
@@ -473,8 +472,6 @@ failed:
 
     if (peers->next) {
 
-        /* ngx_unlock_mutex(peers->mutex); */
-
         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "backup servers");
 
         rrp->peers = peers->next;
@@ -486,13 +483,15 @@ failed:
              rrp->tried[i] = 0;
         }
 
+        ngx_http_upstream_rr_peers_unlock(peers);
+
         rc = ngx_http_upstream_get_round_robin_peer(pc, rrp);
 
         if (rc != NGX_BUSY) {
             return rc;
         }
 
-        /* ngx_lock_mutex(peers->mutex); */
+        ngx_http_upstream_rr_peers_wlock(peers);
     }
 
     /* all peers failed, mark them as live for quick recovery */
@@ -501,7 +500,7 @@ failed:
         peer->fails = 0;
     }
 
-    /* ngx_unlock_mutex(peers->mutex); */
+    ngx_http_upstream_rr_peers_unlock(peers);
 
     pc->name = peers->name;
 
@@ -608,11 +607,12 @@ ngx_http_upstream_free_round_robin_peer(
         return;
     }
 
+    ngx_http_upstream_rr_peers_rlock(rrp->peers);
+    ngx_http_upstream_rr_peer_lock(rrp->peers, peer);
+
     if (state & NGX_PEER_FAILED) {
         now = ngx_time();
 
-        /* ngx_lock_mutex(rrp->peers->mutex); */
-
         peer->fails++;
         peer->accessed = now;
         peer->checked = now;
@@ -629,8 +629,6 @@ ngx_http_upstream_free_round_robin_peer(
             peer->effective_weight = 0;
         }
 
-        /* ngx_unlock_mutex(rrp->peers->mutex); */
-
     } else {
 
         /* mark peer live if check passed */
@@ -642,11 +640,12 @@ ngx_http_upstream_free_round_robin_peer(
 
     peer->conns--;
 
+    ngx_http_upstream_rr_peer_unlock(rrp->peers, peer);
+    ngx_http_upstream_rr_peers_unlock(rrp->peers);
+
     if (pc->tries) {
         pc->tries--;
     }
-
-    /* ngx_unlock_mutex(rrp->peers->mutex); */
 }
 
 
@@ -664,9 +663,6 @@ ngx_http_upstream_set_round_robin_peer_s
 
     peer = rrp->current;
 
-    /* TODO: threads only mutex */
-    /* ngx_lock_mutex(rrp->peers->mutex); */
-
     ssl_session = peer->ssl_session;
 
     rc = ngx_ssl_set_session(pc->connection, ssl_session);
@@ -674,8 +670,6 @@ ngx_http_upstream_set_round_robin_peer_s
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
                    "set session: %p", ssl_session);
 
-    /* ngx_unlock_mutex(rrp->peers->mutex); */
-
     return rc;
 }
 
@@ -700,14 +694,9 @@ ngx_http_upstream_save_round_robin_peer_
 
     peer = rrp->current;
 
-    /* TODO: threads only mutex */
-    /* ngx_lock_mutex(rrp->peers->mutex); */
-
     old_ssl_session = peer->ssl_session;
     peer->ssl_session = ssl_session;
 
-    /* ngx_unlock_mutex(rrp->peers->mutex); */
-
     if (old_ssl_session) {
 
         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
diff -r 682d8222c6b1 -r 3264b7828f72 src/http/ngx_http_upstream_round_robin.h
--- a/src/http/ngx_http_upstream_round_robin.h	Sat Mar 21 14:05:08 2015 +0300
+++ b/src/http/ngx_http_upstream_round_robin.h	Tue Apr 14 19:01:23 2015 +0300
@@ -63,6 +63,13 @@ struct ngx_http_upstream_rr_peers_s {
 };



More information about the nginx-devel mailing list