MEDIUM: listener: let do_unbind_listener() decide whether to close or not

The listener contains all the information needed to decide to close on
unbind or not. The rule is the following (when we're not stopping):

  - worker process unbinding from a worker's FD with socket transfer enabled => keep
  - master process unbinding from a master's inherited FD => keep
  - master process unbinding from a master's FD => close
  - master process unbinding from a worker's FD => close
  - worker process unbinding from a master's FD => close
  - worker process unbinding from a worker's FD => close

Let's translate that into the function and stop using the do_close
argument that is a bit obscure for callers. It was not yet removed
to ease code testing.
diff --git a/src/listener.c b/src/listener.c
index 9246353..5002879 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -581,14 +581,32 @@
 	}
 
  out_close:
-	if (do_close) {
-		listener->rx.flags &= ~RX_F_BOUND;
-		if (listener->rx.fd != -1)
-			fd_delete(listener->rx.fd);
-		listener->rx.fd = -1;
-		if (listener->state > LI_ASSIGNED)
-			listener_set_state(listener, LI_ASSIGNED);
-	}
+	/* There are a number of situations where we prefer to keep the FD and
+	 * not to close it (unless we're stopping, of course):
+	 *   - worker process unbinding from a worker's FD with socket transfer enabled => keep
+	 *   - master process unbinding from a master's inherited FD => keep
+	 *   - master process unbinding from a master's FD => close
+	 *   - master process unbinding from a worker's FD => close
+	 *   - worker process unbinding from a master's FD => close
+	 *   - worker process unbinding from a worker's FD => close
+	 */
+
+	if (!stopping && !master &&
+	    !(listener->options & LI_O_MWORKER) &&
+	    (global.tune.options & GTUNE_SOCKET_TRANSFER))
+		return;
+
+	if (!stopping && master &&
+	    listener->options & LI_O_MWORKER &&
+	    listener->rx.flags & RX_F_INHERITED)
+		return;
+
+	listener->rx.flags &= ~RX_F_BOUND;
+	if (listener->rx.fd != -1)
+		fd_delete(listener->rx.fd);
+	listener->rx.fd = -1;
+	if (listener->state > LI_ASSIGNED)
+		listener_set_state(listener, LI_ASSIGNED);
 }
 
 /* This function closes the listening socket for the specified listener,