MINOR: config: Add threads support for "process" option on "bind" lines

It is now possible on a "bind" line (or a "stats socket" line) to specify the
thread set allowed to process listener's connections. For instance:

    # HTTPS connections will be processed by all threads but the first and HTTP
    # connection will be processed on the first thread.
    bind *:80 process 1/1
    bind *:443 ssl crt mycert.pem process 1/2-
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 13c4f9e..e756d41 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -10858,23 +10858,29 @@
   the server's preference is enforced. This option is also available on
   global statement "ssl-default-bind-options".
 
-process [ all | odd | even | <process_num>[-[<process_num>]] ]
-  This restricts the list of processes on which this listener is allowed to
-  run. It does not enforce any process but eliminates those which do not match.
-  If the frontend uses a "bind-process" setting, the intersection between the
-  two is applied. If in the end the listener is not allowed to run on any
-  remaining process, a warning is emitted, and the listener will either run on
-  the first process of the listener if a single process was specified, or on
-  all of its processes if multiple processes were specified. For the unlikely
-  case where several ranges are needed, this directive may be repeated. Ranges
-  can be partially defined. The higher bound can be omitted. In such case, it
-  is replaced by the corresponding maximum value. The main purpose of this
-  directive is to be used with the stats sockets and have one different socket
-  per process. The second purpose is to have multiple bind lines sharing the
-  same IP:port but not the same process in a listener, so that the system can
-  distribute the incoming connections into multiple queues and allow a smoother
-  inter-process load balancing. Currently Linux 3.9 and above is known for
-  supporting this. See also "bind-process" and "nbproc".
+process <process-set>[/<thread-set>]
+  This restricts the list of processes and/or threads on which this listener is
+  allowed to run. It does not enforce any process but eliminates those which do
+  not match.  If the frontend uses a "bind-process" setting, the intersection
+  between the two is applied. If in the end the listener is not allowed to run
+  on any remaining process, a warning is emitted, and the listener will either
+  run on the first process of the listener if a single process was specified,
+  or on all of its processes if multiple processes were specified. If a thread
+  set is specified, it limits the threads allowed to process inoming
+  connections for this listener, for the corresponding process set. For the
+  unlikely case where several ranges are needed, this directive may be
+  repeated. <process-set> and <thread-set> must use the format
+
+      all | odd | even | number[-[number]]
+
+  Ranges can be partially defined. The higher bound can be omitted. In such
+  case, it is replaced by the corresponding maximum value. The main purpose of
+  this directive is to be used with the stats sockets and have one different
+  socket per process. The second purpose is to have multiple bind lines sharing
+  the same IP:port but not the same process in a listener, so that the system
+  can distribute the incoming connections into multiple queues and allow a
+  smoother inter-process load balancing. Currently Linux 3.9 and above is known
+  for supporting this. See also "bind-process" and "nbproc".
 
 ssl
   This setting is only available when support for OpenSSL was built in. It
diff --git a/include/types/listener.h b/include/types/listener.h
index b92c35e..c55569c 100644
--- a/include/types/listener.h
+++ b/include/types/listener.h
@@ -33,6 +33,7 @@
 #include <common/config.h>
 #include <common/mini-clist.h>
 #include <common/hathreads.h>
+#include <common/standard.h>
 
 #include <types/obj_type.h>
 #include <eb32tree.h>
@@ -159,6 +160,7 @@
 	int is_ssl;                /* SSL is required for these listeners */
 	int generate_certs;        /* 1 if generate-certificates option is set, else 0 */
 	unsigned long bind_proc;   /* bitmask of processes allowed to use these listeners */
+	unsigned long bind_thread[LONGBITS]; /* bitmask of threads (per processes) allowed to use these listeners */
 	struct {                   /* UNIX socket permissions */
 		uid_t uid;         /* -1 to leave unchanged */
 		gid_t gid;         /* -1 to leave unchanged */
diff --git a/src/listener.c b/src/listener.c
index c82ba36..09d38ac 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -941,14 +941,32 @@
 /* parse the "process" bind keyword */
 static int bind_parse_process(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
 {
-	unsigned long set = 0;
+	char *slash;
+	unsigned long proc = 0, thread = 0;
+	int i;
 
-	if (parse_process_number(args[cur_arg + 1], &set, NULL, err)) {
+	if ((slash = strchr(args[cur_arg + 1], '/')) != NULL)
+		*slash = 0;
+
+	if (parse_process_number(args[cur_arg + 1], &proc, NULL, err)) {
 		memprintf(err, "'%s' : %s", args[cur_arg], *err);
 		return ERR_ALERT | ERR_FATAL;
 	}
 
+	if (slash) {
+		if (parse_process_number(slash+1, &thread, NULL, err)) {
+			memprintf(err, "'%s' : %s", args[cur_arg], *err);
+			return ERR_ALERT | ERR_FATAL;
+		}
+		*slash = '/';
+	}
+
-	conf->bind_proc |= set;
+	conf->bind_proc |= proc;
+	if (thread) {
+		for (i = 0; i < LONGBITS; i++)
+			if (!proc || (proc & (1UL << i)))
+				conf->bind_thread[i] |= thread;
+	}
 	return 0;
 }