__decl_thread(HA_RWLOCK_T lock);
struct server *fbck; /* first backup server when !PR_O_USE_ALL_BK, or NULL */
- /* 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 */
- void (*set_server_status_up)(struct server *); /* to be called after status changes to UP */
- void (*set_server_status_down)(struct server *); /* to be called after status changes to DOWN */
- void (*server_take_conn)(struct server *); /* to be called when connection is assigned */
- void (*server_drop_conn)(struct server *); /* to be called when connection is dropped */
+ /* Call backs for some actions. Any of them may be NULL (thus should be ignored).
+ * Those marked "srvlock" will need to be called with the server lock held.
+ * The other ones might take it themselves if needed, based on indications.
+ */
+ void (*update_server_eweight)(struct server *); /* to be called after eweight change // srvlock */
+ void (*set_server_status_up)(struct server *); /* to be called after status changes to UP // srvlock */
+ void (*set_server_status_down)(struct server *); /* to be called after status changes to DOWN // srvlock */
+ void (*server_take_conn)(struct server *, int locked); /* to be called when connection is assigned */
+ void (*server_drop_conn)(struct server *, int locked); /* to be called when connection is dropped */
};
#endif /* _HAPROXY_BACKEND_T_H */
s->flags |= SF_CURR_SESS;
count = _HA_ATOMIC_ADD(&srv->cur_sess, 1);
HA_ATOMIC_UPDATE_MAX(&srv->counters.cur_sess_max, count);
- if (s->be->lbprm.server_take_conn) {
- HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
- s->be->lbprm.server_take_conn(srv);
- HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
- }
+ if (s->be->lbprm.server_take_conn)
+ s->be->lbprm.server_take_conn(srv, 0);
}
/* Now handle synchronously connected sockets. We know the stream-int
* connection or after it has released one. Note that it is possible that
* the server has been moved out of the tree due to failed health-checks.
*
- * The server's lock must be held. The lbprm's lock will be used.
+ * <locked> must reflect the server's lock ownership. The lbprm's lock will
+ * be used.
*/
-static void fas_srv_reposition(struct server *s)
+static void fas_srv_reposition(struct server *s, int locked)
{
+ if (!locked)
+ HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
+
HA_RWLOCK_WRLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
if (s->lb_tree) {
fas_dequeue_srv(s);
fas_queue_srv(s);
}
HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
+
+ if (!locked)
+ HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
}
/* This function updates the server trees according to server <srv>'s new
* connection or after it has released one. Note that it is possible that
* the server has been moved out of the tree due to failed health-checks.
*
- * The server's lock must be held. The lbprm's lock will be used.
+ * <locked> must reflect the server's lock ownership. The lbprm's lock will
+ * be used.
*/
-static void fwlc_srv_reposition(struct server *s)
+static void fwlc_srv_reposition(struct server *s, int locked)
{
+ if (!locked)
+ HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
+
HA_RWLOCK_WRLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
if (s->lb_tree) {
fwlc_dequeue_srv(s);
fwlc_queue_srv(s, s->cur_eweight);
}
HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
+
+ if (!locked)
+ HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
}
/* This function updates the server trees according to server <srv>'s new
_HA_ATOMIC_ADD(&srv->proxy->served, 1);
__ha_barrier_atomic_store();
if (px->lbprm.server_take_conn)
- px->lbprm.server_take_conn(srv);
+ px->lbprm.server_take_conn(srv, 1);
stream_add_srv_conn(p->strm, srv);
task_wakeup(p->strm->task, TASK_WOKEN_RES);
_HA_ATOMIC_SUB(&oldsrv->served, 1);
_HA_ATOMIC_SUB(&oldsrv->proxy->served, 1);
__ha_barrier_atomic_store();
- if (oldsrv->proxy->lbprm.server_drop_conn) {
- HA_SPIN_LOCK(SERVER_LOCK, &oldsrv->lock);
- oldsrv->proxy->lbprm.server_drop_conn(oldsrv);
- HA_SPIN_UNLOCK(SERVER_LOCK, &oldsrv->lock);
- }
+ if (oldsrv->proxy->lbprm.server_drop_conn)
+ oldsrv->proxy->lbprm.server_drop_conn(oldsrv, 0);
stream_del_srv_conn(sess);
}
_HA_ATOMIC_ADD(&newsrv->served, 1);
_HA_ATOMIC_ADD(&newsrv->proxy->served, 1);
__ha_barrier_atomic_store();
- if (newsrv->proxy->lbprm.server_take_conn) {
- HA_SPIN_LOCK(SERVER_LOCK, &newsrv->lock);
- newsrv->proxy->lbprm.server_take_conn(newsrv);
- HA_SPIN_UNLOCK(SERVER_LOCK, &newsrv->lock);
- }
+ if (newsrv->proxy->lbprm.server_take_conn)
+ newsrv->proxy->lbprm.server_take_conn(newsrv, 0);
stream_add_srv_conn(sess, newsrv);
}
}