MINOR: threads/mailers: Add a lock to protect queues of email alerts

This commit is contained in:
Christopher Faulet 2017-10-23 15:54:24 +02:00 committed by Willy Tarreau
parent 88ce5d18a5
commit c2a89a6aed
3 changed files with 13 additions and 4 deletions

View File

@ -170,6 +170,7 @@ enum lock_label {
SPOE_APPLET_LOCK, SPOE_APPLET_LOCK,
DNS_LOCK, DNS_LOCK,
PID_LIST_LOCK, PID_LIST_LOCK,
EMAIL_ALERTS_LOCK,
LOCK_LABELS LOCK_LABELS
}; };
struct lock_stat { struct lock_stat {
@ -258,7 +259,7 @@ static inline void show_lock_stats()
"UPDATED_SERVERS", "LBPRM", "SIGNALS", "STK_TABLE", "STK_SESS", "UPDATED_SERVERS", "LBPRM", "SIGNALS", "STK_TABLE", "STK_SESS",
"APPLETS", "PEER", "BUF_WQ", "STREAMS", "SSL", "SSL_GEN_CERTS", "APPLETS", "PEER", "BUF_WQ", "STREAMS", "SSL", "SSL_GEN_CERTS",
"PATREF", "PATEXP", "PATLRU", "VARS", "COMP_POOL", "LUA", "PATREF", "PATEXP", "PATLRU", "VARS", "COMP_POOL", "LUA",
"NOTIF", "SPOE_APPLET", "DNS", "PID_LIST" }; "NOTIF", "SPOE_APPLET", "DNS", "PID_LIST", "EMAIL_ALERTS" };
int lbl; int lbl;
for (lbl = 0; lbl < LOCK_LABELS; lbl++) { for (lbl = 0; lbl < LOCK_LABELS; lbl++) {

View File

@ -239,6 +239,9 @@ struct email_alertq {
* code even though they are not checks. This structure * code even though they are not checks. This structure
* is as a parameter to the check code. * is as a parameter to the check code.
* Each check corresponds to a mailer */ * Each check corresponds to a mailer */
#ifdef USE_THREAD
HA_SPINLOCK_T lock;
#endif
}; };
struct proxy { struct proxy {

View File

@ -851,7 +851,7 @@ static void event_srv_chk_r(struct connection *conn)
check->code = str2uic(check->bi->data + 9); check->code = str2uic(check->bi->data + 9);
desc = ltrim(check->bi->data + 12, ' '); desc = ltrim(check->bi->data + 12, ' ');
if ((s->proxy->options & PR_O_DISABLE404) && if ((s->proxy->options & PR_O_DISABLE404) &&
(s->next_state != SRV_ST_STOPPED) && (check->code == 404)) { (s->next_state != SRV_ST_STOPPED) && (check->code == 404)) {
/* 404 may be accepted as "stopping" only if the server was up */ /* 404 may be accepted as "stopping" only if the server was up */
@ -3078,13 +3078,14 @@ static struct task *process_email_alert(struct task *t)
q = container_of(check, typeof(*q), check); q = container_of(check, typeof(*q), check);
SPIN_LOCK(EMAIL_ALERTS_LOCK, &q->lock);
while (1) { while (1) {
if (!(check->state & CHK_ST_ENABLED)) { if (!(check->state & CHK_ST_ENABLED)) {
if (LIST_ISEMPTY(&q->email_alerts)) { if (LIST_ISEMPTY(&q->email_alerts)) {
/* All alerts processed, queue the task */ /* All alerts processed, queue the task */
t->expire = TICK_ETERNITY; t->expire = TICK_ETERNITY;
task_queue(t); task_queue(t);
return t; goto end;
} }
alert = LIST_NEXT(&q->email_alerts, typeof(alert), list); alert = LIST_NEXT(&q->email_alerts, typeof(alert), list);
@ -3106,6 +3107,8 @@ static struct task *process_email_alert(struct task *t)
check->server = NULL; check->server = NULL;
check->state &= ~CHK_ST_ENABLED; check->state &= ~CHK_ST_ENABLED;
} }
end:
SPIN_UNLOCK(EMAIL_ALERTS_LOCK, &q->lock);
return t; return t;
} }
@ -3132,7 +3135,7 @@ int init_email_alert(struct mailers *mls, struct proxy *p, char **err)
struct task *t; struct task *t;
LIST_INIT(&q->email_alerts); LIST_INIT(&q->email_alerts);
SPIN_INIT(&q->lock);
check->inter = mls->timeout.mail; check->inter = mls->timeout.mail;
check->rise = DEF_AGENT_RISETIME; check->rise = DEF_AGENT_RISETIME;
check->fall = DEF_AGENT_FALLTIME; check->fall = DEF_AGENT_FALLTIME;
@ -3336,8 +3339,10 @@ static int enqueue_one_email_alert(struct proxy *p, struct server *s,
if (!add_tcpcheck_expect_str(&alert->tcpcheck_rules, "221 ")) if (!add_tcpcheck_expect_str(&alert->tcpcheck_rules, "221 "))
goto error; goto error;
SPIN_LOCK(EMAIL_ALERTS_LOCK, &q->lock);
task_wakeup(check->task, TASK_WOKEN_MSG); task_wakeup(check->task, TASK_WOKEN_MSG);
LIST_ADDQ(&q->email_alerts, &alert->list); LIST_ADDQ(&q->email_alerts, &alert->list);
SPIN_UNLOCK(EMAIL_ALERTS_LOCK, &q->lock);
return 1; return 1;
error: error: