BUG/MEDIUM: protocols: add a global lock for the init/deinit stuff

Dragan Dosen found that the listeners lock is not sufficient to protect
the listeners list when proxies are stopping because the listeners are
also unlinked from the protocol list, and under certain situations like
bombing with soft-stop signals or shutting down many frontends in parallel
from multiple CLI connections, it could be possible to provoke multiple
instances of delete_listener() to be called in parallel for different
listeners, thus corrupting the protocol lists.

Such operations are pretty rare, they are performed once per proxy upon
startup and once per proxy on shut down. Thus there is no point trying
to optimize anything and we can use a global lock to protect the protocol
lists during these manipulations.

This fix (or a variant) will have to be backported as far as 1.8.
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index fd7847d..ff252e8 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -1107,6 +1107,9 @@
  * The sockets will be registered but not added to any fd_set, in order not to
  * loose them across the fork(). A call to enable_all_listeners() is needed
  * to complete initialization. The return value is composed from ERR_*.
+ *
+ * Must be called with proto_lock held.
+ *
  */
 static int tcp_bind_listeners(struct protocol *proto, char *errmsg, int errlen)
 {
@@ -1125,6 +1128,9 @@
 /* Add <listener> to the list of tcpv4 listeners, on port <port>. The
  * listener's state is automatically updated from LI_INIT to LI_ASSIGNED.
  * The number of listeners for the protocol is updated.
+ *
+ * Must be called with proto_lock held.
+ *
  */
 static void tcpv4_add_listener(struct listener *listener, int port)
 {
@@ -1140,6 +1146,9 @@
 /* Add <listener> to the list of tcpv6 listeners, on port <port>. The
  * listener's state is automatically updated from LI_INIT to LI_ASSIGNED.
  * The number of listeners for the protocol is updated.
+ *
+ * Must be called with proto_lock held.
+ *
  */
 static void tcpv6_add_listener(struct listener *listener, int port)
 {