MINOR: backend: replace the lbprm lock with an rwlock

It was previously a spinlock, and it happens that a number of LB algos
only lock it for lookups, without performing any modification. Let's
first turn it to an rwlock and w-lock it everywhere. This is strictly
identical.

It was carefully checked that every HA_SPIN_LOCK() was turned to
HA_RWLOCK_WRLOCK() and that HA_SPIN_UNLOCK() was turned to
HA_RWLOCK_WRUNLOCK() on this lock. _INIT and _DESTROY were updated too.
diff --git a/include/haproxy/backend-t.h b/include/haproxy/backend-t.h
index daaf386..bb8ec6f 100644
--- a/include/haproxy/backend-t.h
+++ b/include/haproxy/backend-t.h
@@ -157,7 +157,7 @@
 	int   arg_opt2;			/* extra option 2 for the LB algo (algo-specific) */
 	int   arg_opt3;			/* extra option 3 for the LB algo (algo-specific) */
 	struct server *fbck;		/* first backup server when !PR_O_USE_ALL_BK, or NULL */
-	__decl_thread(HA_SPINLOCK_T lock);
+	__decl_thread(HA_RWLOCK_T lock);
 
 	/* Call backs for some actions. Any of them may be NULL (thus should be ignored). */
 	void (*update_server_eweight)(struct server *);  /* to be called after eweight change */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index cda2590..4d3c8ad 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -3270,7 +3270,7 @@
 			}
 			break;
 		}
-		HA_SPIN_INIT(&curproxy->lbprm.lock);
+		HA_RWLOCK_INIT(&curproxy->lbprm.lock);
 
 		if (curproxy->options & PR_O_LOGASAP)
 			curproxy->to_log &= ~LW_BYTES;
diff --git a/src/haproxy.c b/src/haproxy.c
index 83e57ce..389abb8 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -2685,7 +2685,7 @@
 
 		p0 = p;
 		p = p->next;
-		HA_SPIN_DESTROY(&p0->lbprm.lock);
+		HA_RWLOCK_DESTROY(&p0->lbprm.lock);
 		HA_SPIN_DESTROY(&p0->lock);
 		free(p0);
 	}/* end while(p) */
diff --git a/src/lb_chash.c b/src/lb_chash.c
index 55417b5..a37a40f 100644
--- a/src/lb_chash.c
+++ b/src/lb_chash.c
@@ -124,7 +124,7 @@
 	if (!srv_lb_status_changed(srv))
                return;
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
 	if (srv_willbe_usable(srv))
 		goto out_update_state;
@@ -162,7 +162,7 @@
  out_update_state:
 	srv_lb_commit_status(srv);
 
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 }
 
 /* This function updates the server trees according to server <srv>'s new
@@ -181,7 +181,7 @@
 	if (!srv_lb_status_changed(srv))
                return;
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
 	if (!srv_willbe_usable(srv))
 		goto out_update_state;
@@ -224,7 +224,7 @@
  out_update_state:
 	srv_lb_commit_status(srv);
 
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 }
 
 /* This function must be called after an update to server <srv>'s effective
@@ -264,7 +264,7 @@
 		return;
 	}
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
 	/* only adjust the server's presence in the tree */
 	chash_queue_dequeue_srv(srv);
@@ -277,7 +277,7 @@
 	update_backend_weight(p);
 	srv_lb_commit_status(srv);
 
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 }
 
 /*
@@ -324,7 +324,7 @@
 	unsigned int dn, dp;
 	int loop;
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
 	if (p->srv_act)
 		root = &p->lbprm.chash.act;
@@ -379,7 +379,7 @@
 	}
 
  out:
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 	return nsrv;
 }
 
@@ -395,7 +395,7 @@
 	srv = avoided = NULL;
 	avoided_node = NULL;
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 	if (p->srv_act)
 		root = &p->lbprm.chash.act;
 	else if (p->lbprm.fbck) {
@@ -454,7 +454,7 @@
 	}
 
  out:
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 	return srv;
 }
 
diff --git a/src/lb_fas.c b/src/lb_fas.c
index 0fcd5e3..43ff6a5 100644
--- a/src/lb_fas.c
+++ b/src/lb_fas.c
@@ -65,12 +65,12 @@
  */
 static void fas_srv_reposition(struct server *s)
 {
-	HA_SPIN_LOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
 	if (s->lb_tree) {
 		fas_dequeue_srv(s);
 		fas_queue_srv(s);
 	}
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
 }
 
 /* This function updates the server trees according to server <srv>'s new
@@ -91,7 +91,7 @@
 	if (srv_willbe_usable(srv))
 		goto out_update_state;
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
 	if (!srv_currently_usable(srv))
 		/* server was already down */
@@ -124,7 +124,7 @@
  out_update_backend:
 	/* check/update tot_used, tot_weight */
 	update_backend_weight(p);
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
  out_update_state:
 	srv_lb_commit_status(srv);
@@ -149,7 +149,7 @@
 	if (!srv_willbe_usable(srv))
 		goto out_update_state;
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
 	if (srv_currently_usable(srv))
 		/* server was already up */
@@ -188,7 +188,7 @@
  out_update_backend:
 	/* check/update tot_used, tot_weight */
 	update_backend_weight(p);
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
  out_update_state:
 	srv_lb_commit_status(srv);
@@ -231,7 +231,7 @@
 		return;
 	}
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
 	if (srv->lb_tree)
 		fas_dequeue_srv(srv);
@@ -247,7 +247,7 @@
 	fas_queue_srv(srv);
 
 	update_backend_weight(p);
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
 	srv_lb_commit_status(srv);
 }
@@ -300,7 +300,7 @@
 
 	srv = avoided = NULL;
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 	if (p->srv_act)
 		node = eb32_first(&p->lbprm.fas.act);
 	else if (p->lbprm.fbck) {
@@ -336,7 +336,7 @@
 	if (!srv)
 		srv = avoided;
   out:
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 	return srv;
 }
 
diff --git a/src/lb_fwlc.c b/src/lb_fwlc.c
index 8eac2c9..882dd7d 100644
--- a/src/lb_fwlc.c
+++ b/src/lb_fwlc.c
@@ -63,12 +63,12 @@
  */
 static void fwlc_srv_reposition(struct server *s)
 {
-	HA_SPIN_LOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
 	if (s->lb_tree) {
 		fwlc_dequeue_srv(s);
 		fwlc_queue_srv(s);
 	}
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
 }
 
 /* This function updates the server trees according to server <srv>'s new
@@ -88,7 +88,7 @@
 
 	if (srv_willbe_usable(srv))
 		goto out_update_state;
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
 
 	if (!srv_currently_usable(srv))
@@ -122,7 +122,7 @@
 out_update_backend:
 	/* check/update tot_used, tot_weight */
 	update_backend_weight(p);
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
  out_update_state:
 	srv_lb_commit_status(srv);
@@ -147,7 +147,7 @@
 	if (!srv_willbe_usable(srv))
 		goto out_update_state;
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
 	if (srv_currently_usable(srv))
 		/* server was already up */
@@ -186,7 +186,7 @@
  out_update_backend:
 	/* check/update tot_used, tot_weight */
 	update_backend_weight(p);
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
  out_update_state:
 	srv_lb_commit_status(srv);
@@ -229,7 +229,7 @@
 		return;
 	}
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
 	if (srv->lb_tree)
 		fwlc_dequeue_srv(srv);
@@ -245,7 +245,7 @@
 	fwlc_queue_srv(srv);
 
 	update_backend_weight(p);
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
 	srv_lb_commit_status(srv);
 }
@@ -298,7 +298,7 @@
 
 	srv = avoided = NULL;
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 	if (p->srv_act)
 		node = eb32_first(&p->lbprm.fwlc.act);
 	else if (p->lbprm.fbck) {
@@ -334,7 +334,7 @@
 	if (!srv)
 		srv = avoided;
  out:
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 	return srv;
 }
 
diff --git a/src/lb_fwrr.c b/src/lb_fwrr.c
index 05ae5f6..e2cdd9f 100644
--- a/src/lb_fwrr.c
+++ b/src/lb_fwrr.c
@@ -43,7 +43,7 @@
 	if (srv_willbe_usable(srv))
 		goto out_update_state;
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
 	if (!srv_currently_usable(srv))
 		/* server was already down */
@@ -79,7 +79,7 @@
 out_update_backend:
 	/* check/update tot_used, tot_weight */
 	update_backend_weight(p);
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
  out_update_state:
 	srv_lb_commit_status(srv);
@@ -105,7 +105,7 @@
 	if (!srv_willbe_usable(srv))
 		goto out_update_state;
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
 	if (srv_currently_usable(srv))
 		/* server was already up */
@@ -147,7 +147,7 @@
 out_update_backend:
 	/* check/update tot_used, tot_weight */
 	update_backend_weight(p);
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
  out_update_state:
 	srv_lb_commit_status(srv);
@@ -191,7 +191,7 @@
 		return;
 	}
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
 	grp = (srv->flags & SRV_F_BACKUP) ? &p->lbprm.fwrr.bck : &p->lbprm.fwrr.act;
 	grp->next_weight = grp->next_weight - srv->cur_eweight + srv->next_eweight;
@@ -239,7 +239,7 @@
 	}
 
 	update_backend_weight(p);
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 
 	srv_lb_commit_status(srv);
 }
@@ -514,7 +514,7 @@
 	struct fwrr_group *grp;
 	int switched;
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 	if (p->srv_act)
 		grp = &p->lbprm.fwrr.act;
 	else if (p->lbprm.fbck) {
@@ -611,7 +611,7 @@
 		}
 	}
  out:
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
 	return srv;
 }
 
diff --git a/src/lb_map.c b/src/lb_map.c
index ef32deb..1432913 100644
--- a/src/lb_map.c
+++ b/src/lb_map.c
@@ -32,11 +32,11 @@
 		goto out_update_state;
 
 	/* FIXME: could be optimized since we know what changed */
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 	recount_servers(p);
 	update_backend_weight(p);
 	recalc_server_map(p);
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
  out_update_state:
 	srv_lb_commit_status(srv);
 }
@@ -56,11 +56,11 @@
 		goto out_update_state;
 
 	/* FIXME: could be optimized since we know what changed */
-	HA_SPIN_LOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
 	recount_servers(p);
 	update_backend_weight(p);
 	recalc_server_map(p);
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &p->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
  out_update_state:
 	srv_lb_commit_status(srv);
 }
@@ -216,7 +216,7 @@
 	int newidx, avoididx;
 	struct server *srv, *avoided;
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &px->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &px->lbprm.lock);
 	if (px->lbprm.tot_weight == 0) {
 		avoided = NULL;
 		goto out;
@@ -248,7 +248,7 @@
 		px->lbprm.map.rr_idx = avoididx;
 
   out:
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &px->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &px->lbprm.lock);
 	/* return NULL or srvtoavoid if found */
 	return avoided;
 }
@@ -265,10 +265,10 @@
 {
 	struct server *srv = NULL;
 
-	HA_SPIN_LOCK(LBPRM_LOCK, &px->lbprm.lock);
+	HA_RWLOCK_WRLOCK(LBPRM_LOCK, &px->lbprm.lock);
 	if (px->lbprm.tot_weight)
 		srv = px->lbprm.map.srv[hash % px->lbprm.tot_weight];
-	HA_SPIN_UNLOCK(LBPRM_LOCK, &px->lbprm.lock);
+	HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &px->lbprm.lock);
 	return srv;
 }