]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: threads/checks: Add a lock to protect the pid list used by external checks
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 20 Oct 2017 13:40:23 +0000 (15:40 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 31 Oct 2017 12:58:33 +0000 (13:58 +0100)
include/common/hathreads.h
src/checks.c

index 242bece4e472f216c850f8ca487f25b3ddadb26a..f68dc7ee1befa8220cc714f0102910f929e1b41c 100644 (file)
@@ -169,6 +169,7 @@ enum lock_label {
        NOTIF_LOCK,
        SPOE_APPLET_LOCK,
        DNS_LOCK,
+       PID_LIST_LOCK,
        LOCK_LABELS
 };
 struct lock_stat {
@@ -257,7 +258,7 @@ static inline void show_lock_stats()
                                           "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" };
+                                          "NOTIF", "SPOE_APPLET", "DNS", "PID_LIST" };
        int lbl;
 
        for (lbl = 0; lbl < LOCK_LABELS; lbl++) {
index ed99bb56ac124208a98b6274df5ef533cd96d2bc..cf1c59e4c0d767c7b41e40429b3ad4b745eaa940 100644 (file)
@@ -35,6 +35,7 @@
 #include <common/mini-clist.h>
 #include <common/standard.h>
 #include <common/time.h>
+#include <common/hathreads.h>
 
 #include <types/global.h>
 #include <types/dns.h>
@@ -1582,6 +1583,9 @@ static int connect_conn_chk(struct task *t)
 
 static struct list pid_list = LIST_HEAD_INIT(pid_list);
 static struct pool_head *pool2_pid_list;
+#ifdef USE_THREAD
+HA_SPINLOCK_T pid_list_lock;
+#endif
 
 void block_sigchld(void)
 {
@@ -1612,7 +1616,11 @@ static struct pid_list *pid_list_add(pid_t pid, struct task *t)
        elem->exited = 0;
        check->curpid = elem;
        LIST_INIT(&elem->list);
+
+       SPIN_LOCK(PID_LIST_LOCK, &pid_list_lock);
        LIST_ADD(&pid_list, &elem->list);
+       SPIN_UNLOCK(PID_LIST_LOCK, &pid_list_lock);
+
        return elem;
 }
 
@@ -1623,7 +1631,10 @@ static void pid_list_del(struct pid_list *elem)
        if (!elem)
                return;
 
+       SPIN_LOCK(PID_LIST_LOCK, &pid_list_lock);
        LIST_DEL(&elem->list);
+       SPIN_UNLOCK(PID_LIST_LOCK, &pid_list_lock);
+
        if (!elem->exited)
                kill(elem->pid, SIGTERM);
 
@@ -1637,15 +1648,17 @@ static void pid_list_expire(pid_t pid, int status)
 {
        struct pid_list *elem;
 
+       SPIN_LOCK(PID_LIST_LOCK, &pid_list_lock);
        list_for_each_entry(elem, &pid_list, list) {
                if (elem->pid == pid) {
                        elem->t->expire = now_ms;
                        elem->status = status;
                        elem->exited = 1;
                        task_wakeup(elem->t, TASK_WOKEN_IO);
-                       return;
+                       break;
                }
        }
+       SPIN_UNLOCK(PID_LIST_LOCK, &pid_list_lock);
 }
 
 static void sigchld_handler(struct sig_handler *sh)
@@ -1676,6 +1689,8 @@ static int init_pid_list(void)
                return 1;
        }
 
+       SPIN_INIT(&pid_list_lock);
+
        return 0;
 }