MINOR: listener: new function listener_release

Instead of duplicating some sensitive listener-specific code in the
session and in the stream code, let's call listener_release() when
releasing a connection attached to a listener.
diff --git a/include/proto/listener.h b/include/proto/listener.h
index 7fdb1cf..1860953 100644
--- a/include/proto/listener.h
+++ b/include/proto/listener.h
@@ -102,6 +102,12 @@
  */
 void listener_accept(int fd);
 
+/* Notify the listener that a connection initiated from it was released. This
+ * is used to keep the connection count consistent and to possibly re-open
+ * listening when it was limited.
+ */
+void listener_release(struct listener *l);
+
 /*
  * Registers the bind keyword list <kwl> as a list of valid keywords for next
  * parsing sessions.
diff --git a/src/listener.c b/src/listener.c
index 0af49b0..e6f89f9 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -588,6 +588,29 @@
 	return;
 }
 
+/* Notify the listener that a connection initiated from it was released. This
+ * is used to keep the connection count consistent and to possibly re-open
+ * listening when it was limited.
+ */
+void listener_release(struct listener *l)
+{
+	struct proxy *fe = l->bind_conf->frontend;
+
+	if (!(l->options & LI_O_UNLIMITED))
+		actconn--;
+	l->nbconn--;
+	if (l->state == LI_FULL)
+		resume_listener(l);
+
+	/* Dequeues all of the listeners waiting for a resource */
+	if (!LIST_ISEMPTY(&global_listener_queue))
+		dequeue_all_listeners(&global_listener_queue);
+
+	if (!LIST_ISEMPTY(&fe->listener_queue) &&
+	    (!fe->fe_sps_lim || freq_ctr_remain(&fe->fe_sess_per_sec, fe->fe_sps_lim, 0) > 0))
+		dequeue_all_listeners(&fe->listener_queue);
+}
+
 /*
  * Registers the bind keyword list <kwl> as a list of valid keywords for next
  * parsing sessions.
diff --git a/src/session.c b/src/session.c
index 68a4303..22f6b58 100644
--- a/src/session.c
+++ b/src/session.c
@@ -376,20 +376,7 @@
 	conn_free(conn);
 
 	sess->fe->feconn--;
-
-	if (!(sess->listener->options & LI_O_UNLIMITED))
-		actconn--;
-	sess->listener->nbconn--;
-	if (sess->listener->state == LI_FULL)
-		resume_listener(sess->listener);
-
-	/* Dequeues all of the listeners waiting for a resource */
-	if (!LIST_ISEMPTY(&global_listener_queue))
-		dequeue_all_listeners(&global_listener_queue);
-
-	if (!LIST_ISEMPTY(&sess->fe->listener_queue) &&
-	    (!sess->fe->fe_sps_lim || freq_ctr_remain(&sess->fe->fe_sess_per_sec, sess->fe->fe_sps_lim, 0) > 0))
-		dequeue_all_listeners(&sess->fe->listener_queue);
+	listener_release(sess->listener);
 
 	task_delete(task);
 	task_free(task);
diff --git a/src/stream.c b/src/stream.c
index d8c1a7e..5489f11 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -2421,21 +2421,8 @@
 	if (s->flags & SF_BE_ASSIGNED)
 		s->be->beconn--;
 
-	if (sess->listener) {
-		if (!(sess->listener->options & LI_O_UNLIMITED))
-			actconn--;
-		sess->listener->nbconn--;
-		if (sess->listener->state == LI_FULL)
-			resume_listener(sess->listener);
-
-		/* Dequeues all of the listeners waiting for a resource */
-		if (!LIST_ISEMPTY(&global_listener_queue))
-			dequeue_all_listeners(&global_listener_queue);
-
-		if (!LIST_ISEMPTY(&sess->fe->listener_queue) &&
-		    (!sess->fe->fe_sps_lim || freq_ctr_remain(&sess->fe->fe_sess_per_sec, sess->fe->fe_sps_lim, 0) > 0))
-			dequeue_all_listeners(&sess->fe->listener_queue);
-	}
+	if (sess->listener)
+		listener_release(sess->listener);
 
 	if (unlikely((global.mode & MODE_DEBUG) &&
 		     (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)))) {