struct list updated_servers = LIST_HEAD_INIT(updated_servers);
+#ifdef USE_THREAD
+HA_SPINLOCK_T updated_servers_lock;
+#endif
+
+static void srv_register_update(struct server *srv);
static void srv_update_state(struct server *srv, int version, char **params);
static int srv_apply_lastaddr(struct server *srv, int *err_code);
static int srv_set_fqdn(struct server *srv, const char *fqdn);
{
struct stream *stream, *stream_bck;
- SPIN_LOCK(SERVER_LOCK, &srv->lock);
list_for_each_entry_safe(stream, stream_bck, &srv->actconns, by_srv)
if (stream->srv_conn == srv)
stream_shutdown(stream, why);
- SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
}
/* Shutdown all connections of all backup servers of a proxy. The caller must
s->op_st_chg.duration = check->duration;
}
- /* Register changes to be applied asynchronously */
- if (LIST_ISEMPTY(&s->update_status))
- LIST_ADDQ(&updated_servers, &s->update_status);
-
+ srv_register_update(s);
for (srv = s->trackers; srv; srv = srv->tracknext)
srv_set_stopped(srv, NULL, NULL);
}
if (s->slowstart <= 0)
s->next_state = SRV_ST_RUNNING;
- /* Register changes to be applied asynchronously */
- if (LIST_ISEMPTY(&s->update_status))
- LIST_ADDQ(&updated_servers, &s->update_status);
-
+ srv_register_update(s);
for (srv = s->trackers; srv; srv = srv->tracknext)
srv_set_running(srv, NULL, NULL);
}
s->op_st_chg.duration = check->duration;
}
- /* Register changes to be applied asynchronously */
- if (LIST_ISEMPTY(&s->update_status))
- LIST_ADDQ(&updated_servers, &s->update_status);
-
+ srv_register_update(s);
for (srv = s->trackers; srv; srv = srv->tracknext)
srv_set_stopping(srv, NULL, NULL);
}
if (cause)
strlcpy2(s->adm_st_chg_cause, cause, sizeof(s->adm_st_chg_cause));
- /* Register changes to be applied asynchronously */
- if (LIST_ISEMPTY(&s->update_status))
- LIST_ADDQ(&updated_servers, &s->update_status);
+ srv_register_update(s);
/* stop going down if the equivalent flag was already present (forced or inherited) */
if (((mode & SRV_ADMF_MAINT) && (s->next_admin & ~mode & SRV_ADMF_MAINT)) ||
s->next_admin &= ~mode;
- /* Register changes to be applied asynchronously */
- if (LIST_ISEMPTY(&s->update_status))
- LIST_ADDQ(&updated_servers, &s->update_status);
+ srv_register_update(s);
+
/* stop going down if the equivalent flag is still present (forced or inherited) */
if (((mode & SRV_ADMF_MAINT) && (s->next_admin & SRV_ADMF_MAINT)) ||
((mode & SRV_ADMF_DRAIN) && (s->next_admin & SRV_ADMF_DRAIN)))
sv->next_eweight = (sv->uweight * w + px->lbprm.wmult - 1) / px->lbprm.wmult;
- /* Register changes to be applied asynchronously */
- if (LIST_ISEMPTY(&sv->update_status))
- LIST_ADDQ(&updated_servers, &sv->update_status);
+ srv_register_update(sv);
}
/*
return NULL;
}
+/* Registers changes to be applied asynchronously */
+static void srv_register_update(struct server *srv)
+{
+ if (LIST_ISEMPTY(&srv->update_status)) {
+ THREAD_WANT_SYNC();
+ SPIN_LOCK(UPDATED_SERVERS_LOCK, &updated_servers_lock);
+ if (LIST_ISEMPTY(&srv->update_status))
+ LIST_ADDQ(&updated_servers, &srv->update_status);
+ SPIN_UNLOCK(UPDATED_SERVERS_LOCK, &updated_servers_lock);
+ }
+}
+
/* Update a server state using the parameters available in the params list */
static void srv_update_state(struct server *srv, int version, char **params)
{
__attribute__((constructor))
static void __server_init(void)
{
+ SPIN_INIT(&updated_servers_lock);
cli_register_kw(&cli_kws);
}
/*
* This function loops on servers registered for asynchronous
* status changes
+ *
+ * NOTE: No needs to lock <updated_servers> list because it is called inside the
+ * sync point.
*/
void servers_update_status(void) {
struct server *s, *stmp;