MEDIUM: mworker: leave when the master die

When the master die, the worker should exit too, this is achieved by
checking if the FD of the socketpair/pipe was closed between the master
and the worker.

In the former architecture of the master-worker, there was only a pipe
between the master and the workers, and it was easy to check an EOF on
the pipe FD to exit() the worker.

With the new architecture, we use a socketpair by process, and this
socketpair is also used to accept new connections with the
listener_accept() callback.

This accept callback can't handle the EOF and the exit of the process,
because it's very specific to the master worker. This is why we
transformed the mworker_pipe_handler() function in a wrapper which check
if there is an EOF and exit the process, and if not call
listener_accept() to achieve the accept.
diff --git a/src/haproxy.c b/src/haproxy.c
index cfa740d..0f593e3 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -2543,43 +2543,58 @@
 	deinit_pollers();
 } /* end deinit() */
 
-void mworker_pipe_handler(int fd)
+
+
+/* This is a wrapper for the sockpair FD, It tests if the socket received an
+ * EOF, if not, it calls listener_accept */
+void mworker_accept_wrapper(int fd)
 {
 	char c;
+	int ret;
 
-	while (read(fd, &c, 1) == -1) {
-		if (errno == EINTR)
-			continue;
-		if (errno == EAGAIN) {
-			fd_cant_recv(fd);
+	while (1) {
+		ret = recv(fd, &c, 1, MSG_PEEK);
+		if (ret == -1) {
+			if (errno == EINTR)
+				continue;
+			if (errno == EAGAIN) {
+				fd_cant_recv(fd);
+				return;
+			}
+			break;
+		} else if (ret > 0) {
+			listener_accept(fd);
 			return;
+		} else if (ret == 0) {
+			/* At this step the master is down before
+			 * this worker perform a 'normal' exit.
+			 * So we want to exit with an error but
+			 * other threads could currently process
+			 * some stuff so we can't perform a clean
+			 * deinit().
+			 */
+			exit(EXIT_FAILURE);
 		}
-		break;
 	}
-
-	/* At this step the master is down before
-	 * this worker perform a 'normal' exit.
-	 * So we want to exit with an error but
-	 * other threads could currently process
-	 * some stuff so we can't perform a clean
-	 * deinit().
-	 */
-	exit(EXIT_FAILURE);
 	return;
 }
 
-/* should only be called once per process */
+/*
+ * Should only be called once per process
+ * This function register the accept wrapper for the sockpair of the master worker
+ */
+
 void mworker_pipe_register()
 {
-	if (fdtab[proc_self->ipc_fd[1]].owner)
-		/* already initialized */
-		return;
+	/* The iocb should be already initialized with listener_accept */
+	if (fdtab[proc_self->ipc_fd[1]].iocb != listener_accept)
+		abort();
 
 	fcntl(proc_self->ipc_fd[1], F_SETFL, O_NONBLOCK);
 	/* In multi-tread, we need only one thread to process
 	 * events on the pipe with master
 	 */
-	fd_insert(proc_self->ipc_fd[1], proc_self->ipc_fd, mworker_pipe_handler, 1);
+	fd_insert(proc_self->ipc_fd[1], proc_self->ipc_fd, mworker_accept_wrapper, 1);
 	fd_want_recv(proc_self->ipc_fd[1]);
 }