MINOR: queue: implement pendconn queue locking functions
The new pendconn_queue_lock() and pendconn_queue_unlock() functions are
made to make it more convenient to lock or unlock the pendconn queue
either at the proxy or the server depending on pendconn->srv. This way
it is possible to remove the open-coding of these locks at various places.
These ones have been used in pendconn_unlink() and pendconn_add(), thus
significantly simplifying the logic there.
diff --git a/src/queue.c b/src/queue.c
index 49a4011..71f5e77 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -144,6 +144,30 @@
LIST_INIT(&p->list);
}
+/* Locks the queue the pendconn element belongs to. This relies on both p->px
+ * and p->srv to be properly initialized (which is always the case once the
+ * element has been added).
+ */
+static inline void pendconn_queue_lock(struct pendconn *p)
+{
+ if (p->srv)
+ HA_SPIN_LOCK(SERVER_LOCK, &p->srv->lock);
+ else
+ HA_SPIN_LOCK(PROXY_LOCK, &p->px->lock);
+}
+
+/* Unlocks the queue the pendconn element belongs to. This relies on both p->px
+ * and p->srv to be properly initialized (which is always the case once the
+ * element has been added).
+ */
+static inline void pendconn_queue_unlock(struct pendconn *p)
+{
+ if (p->srv)
+ HA_SPIN_UNLOCK(SERVER_LOCK, &p->srv->lock);
+ else
+ HA_SPIN_UNLOCK(PROXY_LOCK, &p->px->lock);
+}
+
/* Removes the pendconn from the server/proxy queue. At this stage, the
* connection is not really dequeued. It will be done during process_stream().
* This function takes all the required locks for the operation. The caller is
@@ -153,25 +177,13 @@
*/
void pendconn_unlink(struct pendconn *p)
{
- struct server __maybe_unused *sv;
- struct proxy __maybe_unused *px;
-
HA_SPIN_LOCK(PENDCONN_LOCK, &p->lock);
- px = p->px;
- sv = p->srv;
-
- if (sv)
- HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
- else
- HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
+ pendconn_queue_lock(p);
__pendconn_unlink(p);
- if (sv)
- HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
- else
- HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
+ pendconn_queue_unlock(p);
HA_SPIN_UNLOCK(PENDCONN_LOCK, &p->lock);
}
@@ -299,37 +311,39 @@
if (!p)
return NULL;
- srv = objt_server(strm->target);
- px = strm->be;
+ if (strm->flags & SF_ASSIGNED)
+ srv = objt_server(strm->target);
+ else
+ srv = NULL;
+ px = strm->be;
p->target = NULL;
- p->srv = NULL;
+ p->srv = srv;
p->px = px;
p->strm = strm;
p->strm_flags = strm->flags;
HA_SPIN_INIT(&p->lock);
+ pendconn_queue_lock(p);
+
- if ((strm->flags & SF_ASSIGNED) && srv) {
- p->srv = srv;
- HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
+ if (srv) {
srv->nbpend++;
strm->logs.srv_queue_size += srv->nbpend;
if (srv->nbpend > srv->counters.nbpend_max)
srv->counters.nbpend_max = srv->nbpend;
LIST_ADDQ(&srv->pendconns, &p->list);
- strm->pend_pos = p;
- HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
}
else {
- HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
px->nbpend++;
strm->logs.prx_queue_size += px->nbpend;
if (px->nbpend > px->be_counters.nbpend_max)
px->be_counters.nbpend_max = px->nbpend;
LIST_ADDQ(&px->pendconns, &p->list);
- strm->pend_pos = p;
- HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
}
+ strm->pend_pos = p;
+
+ pendconn_queue_unlock(p);
+
HA_ATOMIC_ADD(&px->totpend, 1);
return p;
}