MINOR: proxy; replace the spinlock with an rwlock

This is an anticipation of finer grained locking for the queues. For now
all lock places take a write lock so that there is no difference at all
with previous code.
diff --git a/include/haproxy/proxy-t.h b/include/haproxy/proxy-t.h
index 1e59373..41aca9d 100644
--- a/include/haproxy/proxy-t.h
+++ b/include/haproxy/proxy-t.h
@@ -321,7 +321,7 @@
 		int clientfin;                  /* timeout to apply to client half-closed connections */
 		int serverfin;                  /* timeout to apply to server half-closed connections */
 	} timeout;
-	__decl_thread(HA_SPINLOCK_T lock);      /* may be taken under the server's lock */
+	__decl_thread(HA_RWLOCK_T lock);        /* may be taken under the server's lock */
 
 	char *id, *desc;			/* proxy id (name) and description */
 	struct eb_root pendconns;		/* pending connections with no server assigned yet */
diff --git a/src/haproxy.c b/src/haproxy.c
index cc5cc1a..3e6fd18 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -2697,7 +2697,7 @@
 		p0 = p;
 		p = p->next;
 		HA_RWLOCK_DESTROY(&p0->lbprm.lock);
-		HA_SPIN_DESTROY(&p0->lock);
+		HA_RWLOCK_DESTROY(&p0->lock);
 		free(p0);
 	}/* end while(p) */
 
diff --git a/src/listener.c b/src/listener.c
index 7061f9a..1947fdb 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -295,7 +295,7 @@
 	}
 
 	if (!lpx)
-		HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
+		HA_RWLOCK_WRLOCK(PROXY_LOCK, &px->lock);
 
 	if (!lpr)
 		HA_SPIN_LOCK(PROTO_LOCK, &proto_lock);
@@ -319,7 +319,7 @@
 		HA_SPIN_UNLOCK(PROTO_LOCK, &proto_lock);
 
 	if (!lpx)
-		HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
+		HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock);
 }
 
 /* default function called to suspend a listener: it simply passes the call to
diff --git a/src/proxy.c b/src/proxy.c
index 790d4d0..fa17eeb 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -1041,7 +1041,7 @@
 	/* Default to only allow L4 retries */
 	p->retry_type = PR_RE_CONN_FAILED;
 
-	HA_SPIN_INIT(&p->lock);
+	HA_RWLOCK_INIT(&p->lock);
 }
 
 /* to be called under the proxy lock after stopping some listeners. This will
@@ -1310,7 +1310,7 @@
 {
 	struct listener *l;
 
-	HA_SPIN_LOCK(PROXY_LOCK, &p->lock);
+	HA_RWLOCK_WRLOCK(PROXY_LOCK, &p->lock);
 
 	list_for_each_entry(l, &p->conf.listeners, by_fe)
 		stop_listener(l, 1, 0, 0);
@@ -1320,7 +1320,7 @@
 		p->disabled = 1;
 	}
 
-	HA_SPIN_UNLOCK(PROXY_LOCK, &p->lock);
+	HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &p->lock);
 }
 
 /* This function resumes listening on the specified proxy. It scans all of its
@@ -1559,14 +1559,14 @@
 	/* note: we still lock since we have to be certain that nobody is
 	 * dumping the output while we free.
 	 */
-	HA_SPIN_LOCK(PROXY_LOCK, &proxy->lock);
+	HA_RWLOCK_WRLOCK(PROXY_LOCK, &proxy->lock);
 	if (is_back) {
 		es = HA_ATOMIC_XCHG(&proxy->invalid_rep, es);
 	} else {
 		es = HA_ATOMIC_XCHG(&proxy->invalid_req, es);
 	}
 	free(es);
-	HA_SPIN_UNLOCK(PROXY_LOCK, &proxy->lock);
+	HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &proxy->lock);
 }
 
 /* Configure all proxies which lack a maxconn setting to use the global one by
@@ -1936,9 +1936,9 @@
 	/* Note: this lock is to make sure this doesn't change while another
 	 * thread is in srv_set_dyncookie().
 	 */
-	HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
+	HA_RWLOCK_WRLOCK(PROXY_LOCK, &px->lock);
 	px->ck_opts |= PR_CK_DYNAMIC;
-	HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
+	HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock);
 
 	for (s = px->srv; s != NULL; s = s->next) {
 		HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
@@ -1968,9 +1968,9 @@
 	/* Note: this lock is to make sure this doesn't change while another
 	 * thread is in srv_set_dyncookie().
 	 */
-	HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
+	HA_RWLOCK_WRLOCK(PROXY_LOCK, &px->lock);
 	px->ck_opts &= ~PR_CK_DYNAMIC;
-	HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
+	HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock);
 
 	for (s = px->srv; s != NULL; s = s->next) {
 		HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
@@ -2011,10 +2011,10 @@
 	/* Note: this lock is to make sure this doesn't change while another
 	 * thread is in srv_set_dyncookie().
 	 */
-	HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
+	HA_RWLOCK_WRLOCK(PROXY_LOCK, &px->lock);
 	free(px->dyncookie_key);
 	px->dyncookie_key = newkey;
-	HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
+	HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock);
 
 	for (s = px->srv; s != NULL; s = s->next) {
 		HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
@@ -2052,7 +2052,7 @@
 	/* OK, the value is fine, so we assign it to the proxy and to all of
 	 * its listeners. The blocked ones will be dequeued.
 	 */
-	HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
+	HA_RWLOCK_WRLOCK(PROXY_LOCK, &px->lock);
 
 	px->maxconn = v;
 	list_for_each_entry(l, &px->conf.listeners, by_fe) {
@@ -2063,7 +2063,7 @@
 	if (px->maxconn > px->feconn)
 		dequeue_proxy_listeners(px);
 
-	HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
+	HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock);
 
 	return 1;
 }
@@ -2112,9 +2112,9 @@
 	if (!px->li_ready)
 		return cli_msg(appctx, LOG_NOTICE, "All sockets are already disabled.\n");
 
-	HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
+	HA_RWLOCK_WRLOCK(PROXY_LOCK, &px->lock);
 	ret = pause_proxy(px);
-	HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
+	HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock);
 
 	if (!ret)
 		return cli_err(appctx, "Failed to pause frontend, check logs for precise cause.\n");
@@ -2144,9 +2144,9 @@
 	if (px->li_ready == px->li_all)
 		return cli_msg(appctx, LOG_NOTICE, "All sockets are already enabled.\n");
 
-	HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
+	HA_RWLOCK_WRLOCK(PROXY_LOCK, &px->lock);
 	ret = resume_proxy(px);
-	HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
+	HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock);
 
 	if (!ret)
 		return cli_err(appctx, "Failed to resume frontend, check logs for precise cause (port conflict?).\n");
@@ -2225,7 +2225,7 @@
 	while (appctx->ctx.errors.px) {
 		struct error_snapshot *es;
 
-		HA_SPIN_LOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
+		HA_RWLOCK_WRLOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
 
 		if ((appctx->ctx.errors.flag & 1) == 0) {
 			es = appctx->ctx.errors.px->invalid_req;
@@ -2335,7 +2335,7 @@
 			appctx->ctx.errors.bol = newline;
 		};
 	next:
-		HA_SPIN_UNLOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
+		HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
 		appctx->ctx.errors.bol = 0;
 		appctx->ctx.errors.ptr = -1;
 		appctx->ctx.errors.flag ^= 1;
@@ -2347,7 +2347,7 @@
 	return 1;
 
  cant_send_unlock:
-	HA_SPIN_UNLOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
+	HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
  cant_send:
 	si_rx_room_blk(si);
 	return 0;
diff --git a/src/queue.c b/src/queue.c
index 312c91f..f571878 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -152,7 +152,7 @@
 	if (p->srv)
 		HA_SPIN_LOCK(SERVER_LOCK, &p->srv->lock);
 	else
-		HA_SPIN_LOCK(PROXY_LOCK, &p->px->lock);
+		HA_RWLOCK_WRLOCK(PROXY_LOCK, &p->px->lock);
 }
 
 /* Unlocks the queue the pendconn element belongs to. This relies on both p->px
@@ -164,7 +164,7 @@
 	if (p->srv)
 		HA_SPIN_UNLOCK(SERVER_LOCK, &p->srv->lock);
 	else
-		HA_SPIN_UNLOCK(PROXY_LOCK, &p->px->lock);
+		HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &p->px->lock);
 }
 
 /* Removes the pendconn from the server/proxy queue. At this stage, the
@@ -312,14 +312,14 @@
 	int maxconn;
 
 	HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
-	HA_SPIN_LOCK(PROXY_LOCK,  &p->lock);
+	HA_RWLOCK_WRLOCK(PROXY_LOCK,  &p->lock);
 	maxconn = srv_dynamic_maxconn(s);
 	while (s->served < maxconn) {
 		int ret = pendconn_process_next_strm(s, p);
 		if (!ret)
 			break;
 	}
-	HA_SPIN_UNLOCK(PROXY_LOCK,  &p->lock);
+	HA_RWLOCK_WRUNLOCK(PROXY_LOCK,  &p->lock);
 	HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
 }
 
@@ -444,7 +444,7 @@
 	     ((s != s->proxy->lbprm.fbck) && !(s->proxy->options & PR_O_USE_ALL_BK))))
 		return 0;
 
-	HA_SPIN_LOCK(PROXY_LOCK, &s->proxy->lock);
+	HA_RWLOCK_WRLOCK(PROXY_LOCK, &s->proxy->lock);
 	maxconn = srv_dynamic_maxconn(s);
 	while ((p = pendconn_first(&s->proxy->pendconns))) {
 		if (s->maxconn && s->served + xferred >= maxconn)
@@ -456,7 +456,7 @@
 		task_wakeup(p->strm->task, TASK_WOKEN_RES);
 		xferred++;
 	}
-	HA_SPIN_UNLOCK(PROXY_LOCK, &s->proxy->lock);
+	HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &s->proxy->lock);
 	return xferred;
 }
 
diff --git a/src/server.c b/src/server.c
index 2271f9e..cdb5bce 100644
--- a/src/server.c
+++ b/src/server.c
@@ -139,7 +139,7 @@
 	int addr_len;
 	int port;
 
-	HA_SPIN_LOCK(PROXY_LOCK, &p->lock);
+	HA_RWLOCK_WRLOCK(PROXY_LOCK, &p->lock);
 
 	if ((s->flags & SRV_F_COOKIESET) ||
 	    !(s->proxy->ck_opts & PR_CK_DYNAMIC) ||
@@ -188,7 +188,7 @@
 	if (!(s->next_admin & SRV_ADMF_FMAINT))
 		srv_check_for_dup_dyncookie(s);
  out:
-	HA_SPIN_UNLOCK(PROXY_LOCK, &p->lock);
+	HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &p->lock);
 }
 
 /*