MEDIUM: threads/signal: Add a lock to make signals thread-safe

A global lock has been added to protect the signal processing. So when a signal
it triggered, only one thread will catch it.
diff --git a/src/signal.c b/src/signal.c
index 201c93f..14e4f1e 100644
--- a/src/signal.c
+++ b/src/signal.c
@@ -31,6 +31,10 @@
 sigset_t blocked_sig;
 int signal_pending = 0; /* non-zero if t least one signal remains unprocessed */
 
+#ifdef USE_THREAD
+HA_SPINLOCK_T signals_lock;
+#endif
+
 /* Common signal handler, used by all signals. Received signals are queued.
  * Signal number zero has a specific status, as it cannot be delivered by the
  * system, any function may call it to perform asynchronous signal delivery.
@@ -69,6 +73,9 @@
 	struct signal_descriptor *desc;
 	sigset_t old_sig;
 
+	if (SPIN_TRYLOCK(SIGNALS_LOCK, &signals_lock))
+		return;
+
 	/* block signal delivery during processing */
 	sigprocmask(SIG_SETMASK, &blocked_sig, &old_sig);
 
@@ -95,6 +102,7 @@
 
 	/* restore signal delivery */
 	sigprocmask(SIG_SETMASK, &old_sig, NULL);
+	SPIN_UNLOCK(SIGNALS_LOCK, &signals_lock);
 }
 
 /* perform minimal intializations, report 0 in case of error, 1 if OK. */
@@ -106,6 +114,8 @@
 	memset(signal_queue, 0, sizeof(signal_queue));
 	memset(signal_state, 0, sizeof(signal_state));
 
+	SPIN_INIT(&signals_lock);
+
 	/* Ensure signals are not blocked. Some shells or service managers may
 	 * accidently block all of our signals unfortunately, causing lots of
 	 * zombie processes to remain in the background during reloads.
@@ -140,6 +150,7 @@
 			pool_free2(pool2_sig_handlers, sh);
 		}
 	}
+	SPIN_DESTROY(&signals_lock);
 }
 
 /* Register a function and an integer argument on a signal. A pointer to the