MINOR: threads/mailers: Add a lock to protect queues of email alerts
diff --git a/include/common/hathreads.h b/include/common/hathreads.h
index f68dc7e..25c1737 100644
--- a/include/common/hathreads.h
+++ b/include/common/hathreads.h
@@ -170,6 +170,7 @@
 	SPOE_APPLET_LOCK,
 	DNS_LOCK,
 	PID_LIST_LOCK,
+	EMAIL_ALERTS_LOCK,
 	LOCK_LABELS
 };
 struct lock_stat {
@@ -258,7 +259,7 @@
 					   "UPDATED_SERVERS", "LBPRM", "SIGNALS", "STK_TABLE", "STK_SESS",
 					   "APPLETS", "PEER", "BUF_WQ", "STREAMS", "SSL", "SSL_GEN_CERTS",
 					   "PATREF", "PATEXP", "PATLRU", "VARS", "COMP_POOL", "LUA",
-					   "NOTIF", "SPOE_APPLET", "DNS", "PID_LIST" };
+					   "NOTIF", "SPOE_APPLET", "DNS", "PID_LIST", "EMAIL_ALERTS" };
 	int lbl;
 
 	for (lbl = 0; lbl < LOCK_LABELS; lbl++) {
diff --git a/include/types/proxy.h b/include/types/proxy.h
index 3e0c3ee..719c8dd 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -239,6 +239,9 @@
 					 * code even though they are not checks. This structure
 					 * is as a parameter to the check code.
 					 * Each check corresponds to a mailer */
+#ifdef USE_THREAD
+	HA_SPINLOCK_T lock;
+#endif
 };
 
 struct proxy {
diff --git a/src/checks.c b/src/checks.c
index 0944c0e..d07e508 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -851,7 +851,7 @@
 
 		check->code = str2uic(check->bi->data + 9);
 		desc = ltrim(check->bi->data + 12, ' ');
-		
+
 		if ((s->proxy->options & PR_O_DISABLE404) &&
 			 (s->next_state != SRV_ST_STOPPED) && (check->code == 404)) {
 			/* 404 may be accepted as "stopping" only if the server was up */
@@ -3078,13 +3078,14 @@
 
 	q = container_of(check, typeof(*q), check);
 
+	SPIN_LOCK(EMAIL_ALERTS_LOCK, &q->lock);
 	while (1) {
 		if (!(check->state & CHK_ST_ENABLED)) {
 			if (LIST_ISEMPTY(&q->email_alerts)) {
 				/* All alerts processed, queue the task */
 				t->expire = TICK_ETERNITY;
 				task_queue(t);
-				return t;
+				goto end;
 			}
 
 			alert = LIST_NEXT(&q->email_alerts, typeof(alert), list);
@@ -3106,6 +3107,8 @@
 		check->server         = NULL;
 		check->state         &= ~CHK_ST_ENABLED;
 	}
+  end:
+	SPIN_UNLOCK(EMAIL_ALERTS_LOCK, &q->lock);
 	return t;
 }
 
@@ -3132,7 +3135,7 @@
 		struct task         *t;
 
 		LIST_INIT(&q->email_alerts);
-
+		SPIN_INIT(&q->lock);
 		check->inter = mls->timeout.mail;
 		check->rise = DEF_AGENT_RISETIME;
 		check->fall = DEF_AGENT_FALLTIME;
@@ -3336,8 +3339,10 @@
 	if (!add_tcpcheck_expect_str(&alert->tcpcheck_rules, "221 "))
 		goto error;
 
+	SPIN_LOCK(EMAIL_ALERTS_LOCK, &q->lock);
 	task_wakeup(check->task, TASK_WOKEN_MSG);
 	LIST_ADDQ(&q->email_alerts, &alert->list);
+	SPIN_UNLOCK(EMAIL_ALERTS_LOCK, &q->lock);
 	return 1;
 
 error: