[MEDIUM] signals: add support for registering functions and tasks

The two new functions below make it possible to register any number
of functions or tasks to a system signal. They will be called in the
registration order when the signal is received.

    struct sig_handler *signal_register_fct(int sig, void (*fct)(struct sig_handler *), int arg);
    struct sig_handler *signal_register_task(int sig, struct task *task, int reason);
diff --git a/src/haproxy.c b/src/haproxy.c
index ece9526..d9c3b6a 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -246,17 +246,17 @@
 /*
  * upon SIGUSR1, let's have a soft stop.
  */
-void sig_soft_stop(int sig)
+void sig_soft_stop(struct sig_handler *sh)
 {
 	soft_stop();
+	signal_unregister_handler(sh);
 	pool_gc2();
-	signal_register(sig, SIG_IGN);
 }
 
 /*
  * upon SIGTTOU, we pause everything
  */
-void sig_pause(int sig)
+void sig_pause(struct sig_handler *sh)
 {
 	pause_proxies();
 	pool_gc2();
@@ -265,7 +265,7 @@
 /*
  * upon SIGTTIN, let's have a soft stop.
  */
-void sig_listen(int sig)
+void sig_listen(struct sig_handler *sh)
 {
 	listen_proxies();
 }
@@ -273,7 +273,7 @@
 /*
  * this function dumps every server's state when the process receives SIGHUP.
  */
-void sig_dump_state(int sig)
+void sig_dump_state(struct sig_handler *sh)
 {
 	struct proxy *p = proxy;
 
@@ -319,70 +319,13 @@
 	}
 }
 
-void dump(int sig)
+void dump(struct sig_handler *sh)
 {
-#if 0
-	struct task *t;
-	struct session *s;
-	struct rb_node *node;
-
-	for(node = rb_first(&wait_queue[0]);
-		node != NULL; node = rb_next(node)) {
-		t = rb_entry(node, struct task, rb_node);
-		s = t->context;
-		qfprintf(stderr,"[dump] wq: task %p, still %ld ms, "
-			 "cli=%d, srv=%d, req=%d, rep=%d\n",
-			 s, tv_ms_remain(&now, &t->expire),
-			 s->si[0].state,
-			 s->si[1].state,
-			 s->req->l, s->rep?s->rep->l:0);
-	}
-#endif
 	/* dump memory usage then free everything possible */
 	dump_pools();
 	pool_gc2();
-}
-
-#ifdef DEBUG_MEMORY
-static void fast_stop(void)
-{
-	struct proxy *p;
-	p = proxy;
-	while (p) {
-		p->grace = 0;
-		p = p->next;
-	}
-	soft_stop();
-}
-
-void sig_int(int sig)
-{
-	/* This would normally be a hard stop,
-	   but we want to be sure about deallocation,
-	   and so on, so we do a soft stop with
-	   0 GRACE time
-	*/
-	fast_stop();
-	pool_gc2();
-	/* If we are killed twice, we decide to die */
-	signal_register(sig, SIG_DFL);
 }
 
-void sig_term(int sig)
-{
-	/* This would normally be a hard stop,
-	   but we want to be sure about deallocation,
-	   and so on, so we do a soft stop with
-	   0 GRACE time
-	*/
-	fast_stop();
-	pool_gc2();
-	/* If we are killed twice, we decide to die */
-	signal_register(sig, SIG_DFL);
-}
-#endif
-
-
 /*
  * This function initializes all the necessary variables. It only returns
  * if everything is OK. If something fails, it exits.
@@ -726,6 +669,7 @@
 	struct uri_auth *uap, *ua = NULL;
 	int i;
 
+	deinit_signals();
 	while (p) {
 		free(p->id);
 		free(p->check_req);
@@ -924,6 +868,7 @@
 	pool_destroy2(pool2_capture);
 	pool_destroy2(pool2_appsess);
 	pool_destroy2(pool2_pendconn);
+	pool_destroy2(pool2_sig_handlers);
     
 	if (have_appsession) {
 		pool_destroy2(apools.serverid);
@@ -931,7 +876,6 @@
 	}
 
 	deinit_pollers();
-
 } /* end deinit() */
 
 /* sends the signal <sig> to all pids found in <oldpids>. Returns the number of
@@ -991,19 +935,15 @@
 	FILE *pidfile = NULL;
 	init(argc, argv);
 
-	signal_register(SIGQUIT, dump);
-	signal_register(SIGUSR1, sig_soft_stop);
-	signal_register(SIGHUP, sig_dump_state);
-#ifdef DEBUG_MEMORY
-	signal_register(SIGINT, sig_int);
-	signal_register(SIGTERM, sig_term);
-#endif
+	signal_register_fct(SIGQUIT, dump, SIGQUIT);
+	signal_register_fct(SIGUSR1, sig_soft_stop, SIGUSR1);
+	signal_register_fct(SIGHUP, sig_dump_state, SIGHUP);
 
 	/* Always catch SIGPIPE even on platforms which define MSG_NOSIGNAL.
 	 * Some recent FreeBSD setups report broken pipes, and MSG_NOSIGNAL
 	 * was defined there, so let's stay on the safe side.
 	 */
-	signal(SIGPIPE, SIG_IGN);
+	signal_register_fct(SIGPIPE, NULL, 0);
 
 	/* We will loop at most 100 times with 10 ms delay each time.
 	 * That's at most 1 second. We only send a signal to old pids
@@ -1061,8 +1001,8 @@
 	}
 
 	/* prepare pause/play signals */
-	signal_register(SIGTTOU, sig_pause);
-	signal_register(SIGTTIN, sig_listen);
+	signal_register_fct(SIGTTOU, sig_pause, SIGTTOU);
+	signal_register_fct(SIGTTIN, sig_listen, SIGTTIN);
 
 	/* MODE_QUIET can inhibit alerts and warnings below this line */