BUG/MAJOR: external-checks: use asynchronous signal delivery

There are random segfaults occuring when using external checks. The
reason is that when receiving a SIGCHLD, a call to task_wakeup() is
performed. There are two situations where this causes trouble :
  - the scheduler is in process_running_tasks(), since task_wakeup()
    sets rq_next to NULL, when the former dereferences it to get the
    next pointer, the program crashes ;

  - when another task_wakeup() is being called and during eb_next()
    in process_running_tasks(), because the structure of the run queue
    tree changes while it is being processed.

The solution against this is to use asynchronous signal processing
thanks to the internal signal API. The signal handler is registered,
and upon delivery, the signal is added to the queue and processed
out of any other processing.

This code was stressed at 2500 forks/s and their respective signals
for quite some time and the segfault is now gone.
diff --git a/src/checks.c b/src/checks.c
index 60f1226..ee0295e 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -58,6 +58,7 @@
 #include <proto/proxy.h>
 #include <proto/raw_sock.h>
 #include <proto/server.h>
+#include <proto/signal.h>
 #include <proto/stream_interface.h>
 #include <proto/task.h>
 #include <proto/log.h>
@@ -1603,25 +1604,22 @@
 	}
 }
 
-static void sigchld_handler(int signal)
+static void sigchld_handler(struct sig_handler *sh)
 {
 	pid_t pid;
 	int status;
+
 	while ((pid = waitpid(0, &status, WNOHANG)) > 0)
 		pid_list_expire(pid, status);
 }
 
-static int init_pid_list(void) {
-	struct sigaction action = {
-		.sa_handler = sigchld_handler,
-		.sa_flags = SA_NOCLDSTOP
-	};
-
+static int init_pid_list(void)
+{
 	if (pool2_pid_list != NULL)
 		/* Nothing to do */
 		return 0;
 
-	if (sigaction(SIGCHLD, &action, NULL)) {
+	if (!signal_register_fct(SIGCHLD, sigchld_handler, SIGCHLD)) {
 		Alert("Failed to set signal handler for external health checks: %s. Aborting.\n",
 		      strerror(errno));
 		return 1;