Only in httpd-2.4.7.new: 1
diff -ru httpd-2.4.7/configure httpd-2.4.7.new/configure
--- httpd-2.4.7/configure	2014-01-24 14:18:18.079893836 -0500
+++ httpd-2.4.7.new/configure	2014-01-24 14:17:46.063894273 -0500
@@ -6354,7 +6354,20 @@
 
   APACHE_VAR_SUBST="$APACHE_VAR_SUBST LTCFLAGS"
 
+case $host in
+    *-linux-*)
+        case `uname -r` in
+        # SO_REUSEPORT feature is only being enabled in the Linux kernel newer than 3.9
+        [0-2].* | 3.[0-8].*)
+            ;;
+        * )
+    test "x$silent" != "xyes" && echo "  forcing HAVE_SO_REUSEPORT to \"1\""
+    HAVE_SO_REUSEPORT="1"
 
+            ;;
+        esac
+        ;;
+esac
 
 case $host in
   *-apple-aux3*)
@@ -32191,6 +32204,12 @@
 
 fi
 
+if test "$HAVE_SO_REUSEPORT" = "1"; then
+
+$as_echo "#define HAVE_SO_REUSEPORT 1" >>confdefs.h
+
+fi
+
 if test "$AP_NONBLOCK_WHEN_MULTI_LISTEN" = "1"; then
 
 $as_echo "#define AP_NONBLOCK_WHEN_MULTI_LISTEN 1" >>confdefs.h
diff -ru httpd-2.4.7/configure.in httpd-2.4.7.new/configure.in
--- httpd-2.4.7/configure.in	2014-01-24 14:18:14.009893891 -0500
+++ httpd-2.4.7.new/configure.in	2014-01-24 14:17:42.356894323 -0500
@@ -307,6 +307,19 @@
 APACHE_SUBST(LTCFLAGS)
 
 case $host in
+  *-linux-*)
+      case `uname -r` in
+        #SO_REUSEPORT is only being enabled in Linux kernel 3.9 and newer
+        [[0-2]].* | 3.[[0-8]].* )
+            ;;
+        * )
+            APR_SETVAR(HAVE_SO_REUSEPORT, [1])
+            ;;
+     esac
+     ;;
+esac
+
+case $host in
   *-apple-aux3*)
       APR_SETVAR(SINGLE_LISTEN_UNSERIALIZED_ACCEPT, [1])
       ;;
@@ -761,6 +774,11 @@
               [This platform doesn't suffer from the thundering herd problem])
 fi
 
+if test "$HAVE_SO_REUSEPORT" = "1"; then
+    AC_DEFINE(HAVE_SO_REUSEPORT, 1,
+              [This platform has SO_REUSEPORT feature enabled])
+fi
+
 if test "$AP_NONBLOCK_WHEN_MULTI_LISTEN" = "1"; then
     AC_DEFINE(AP_NONBLOCK_WHEN_MULTI_LISTEN, 1, 
               [Listening sockets are non-blocking when there are more than 1])
diff -ru httpd-2.4.7/include/ap_config_auto.h.in httpd-2.4.7.new/include/ap_config_auto.h.in
--- httpd-2.4.7/include/ap_config_auto.h.in	2014-01-24 14:18:18.140893835 -0500
+++ httpd-2.4.7.new/include/ap_config_auto.h.in	2014-01-24 14:17:46.119894272 -0500
@@ -229,6 +229,9 @@
 /* This platform doesn't suffer from the thundering herd problem */
 #undef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 
+/* Define to 1 if you have SO_REUSEPORT enabled in your kernel. Linux kernel newer than 3.9 has this enabled */
+#undef HAVE_SO_REUSEPORT
+
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 
diff -ru httpd-2.4.7/include/ap_listen.h httpd-2.4.7.new/include/ap_listen.h
--- httpd-2.4.7/include/ap_listen.h	2014-01-24 14:18:18.111893835 -0500
+++ httpd-2.4.7.new/include/ap_listen.h	2014-01-24 14:17:46.075894272 -0500
@@ -79,6 +79,15 @@
 AP_DECLARE_DATA extern ap_listen_rec *ap_listeners;
 
 /**
+ ** The listener array defined for the patch.
+ ** */
+AP_DECLARE_DATA extern ap_listen_rec **mpm_listen;
+
+AP_DECLARE_DATA extern int flag;
+
+AP_DECLARE_DATA extern int num_buckets;
+
+/**
  * Setup all of the defaults for the listener list
  */
 AP_DECLARE(void) ap_listen_pre_config(void);
@@ -91,6 +100,15 @@
  */
 AP_DECLARE(int) ap_setup_listeners(server_rec *s);
 
+/**This function is added for the patch. It creates sockets for the mpm_listen
+ * array, executes the listen and bind on the sockets, and set the sockets to
+ * be active. If HAVE_SO_REUSEPORT is enabled, It will duplicate ap_listeners.
+ * @param s The global server_rec
+ * @param p The config pool
+ * @param num_buckets The total number of listener buckets.
+ * */
+AP_DECLARE(apr_status_t) ap_post_config_listeners(server_rec *s, apr_pool_t *p, int num_buckets);
+
 /**
  * Loop through the global ap_listen_rec list and close each of the sockets.
  */
diff -ru httpd-2.4.7/include/mpm_common.h httpd-2.4.7.new/include/mpm_common.h
--- httpd-2.4.7/include/mpm_common.h	2014-01-24 14:18:18.177893834 -0500
+++ httpd-2.4.7.new/include/mpm_common.h	2014-01-24 14:17:46.168894271 -0500
@@ -267,16 +267,18 @@
  * Write data to the pipe-of-death, signalling that one child process
  * should die.
  * @param pod the pipe-of-death to write to.
+ * @param my_bucket the bucket that holds the dying child process
  */
-AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod);
+AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod, int my_bucket);
 
 /**
  * Write data to the pipe-of-death, signalling that all child process
  * should die.
  * @param pod The pipe-of-death to write to.
+ * @param my_bucket the bucket that holds the dying child process
  * @param num The number of child processes to kill
  */
-AP_DECLARE(void) ap_mpm_pod_killpg(ap_pod_t *pod, int num);
+AP_DECLARE(void) ap_mpm_pod_killpg(ap_pod_t *pod, int my_bucket, int num);
 
 #define AP_MPM_PODX_RESTART_CHAR '$'
 #define AP_MPM_PODX_GRACEFUL_CHAR '!'
diff -ru httpd-2.4.7/server/listen.c httpd-2.4.7.new/server/listen.c
--- httpd-2.4.7/server/listen.c	2014-01-24 14:18:13.756893895 -0500
+++ httpd-2.4.7.new/server/listen.c	2014-01-24 14:21:55.892890864 -0500
@@ -34,6 +34,10 @@
 
 AP_DECLARE_DATA ap_listen_rec *ap_listeners = NULL;
 
+AP_DECLARE_DATA ap_listen_rec **mpm_listen = NULL;
+AP_DECLARE_DATA int flag = 1;
+AP_DECLARE_DATA int num_buckets = 1;
+
 static ap_listen_rec *old_listeners;
 static int ap_listenbacklog;
 static int send_buffer_size;
@@ -131,21 +135,32 @@
     ap_sock_disable_nagle(s);
 #endif
 
-    if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) {
-        ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, APLOGNO(00072)
-                      "make_sock: could not bind to address %pI",
-                      server->bind_addr);
-        apr_socket_close(s);
-        return stat;
-    }
+#if HAVE_SO_REUSEPORT
+#ifndef SO_REUSEPORT
+#define SO_REUSEPORT 15
+    int thesock;
+    apr_os_sock_get(&thesock, s);
+    setsockopt(thesock, SOL_SOCKET, SO_REUSEPORT, (void *)&one, sizeof(int));
+#endif
+#endif
 
-    if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) {
-        ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, APLOGNO(00073)
-                      "make_sock: unable to listen for connections "
-                      "on address %pI",
-                      server->bind_addr);
-        apr_socket_close(s);
-        return stat;
+    if (flag) {
+        if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) {
+            ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, APLOGNO(00072)
+                          "make_sock: could not bind to address %pI",
+                          server->bind_addr);
+            apr_socket_close(s);
+            return stat;
+        }
+
+        if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) {
+            ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, APLOGNO(00073)
+                          "make_sock: unable to listen for connections "
+                          "on address %pI",
+                          server->bind_addr);
+            apr_socket_close(s);
+            return stat;
+        }
     }
 
 #ifdef WIN32
@@ -170,7 +185,7 @@
 #endif
 
     server->sd = s;
-    server->active = 1;
+    server->active = flag;
 
     server->accept_func = NULL;
 
@@ -233,6 +248,87 @@
     }
 }
 
+static ap_listen_rec* ap_duplicate_listener(apr_pool_t *p, ap_listen_rec *lr)
+{
+    apr_status_t stat;
+    int use_nonblock = 0;
+    ap_listen_rec *duplr;
+    duplr  = apr_palloc(p, sizeof(ap_listen_rec));
+    duplr->slave = 0;
+    duplr->protocol = apr_pstrdup(p, lr->protocol);
+    apr_sockaddr_t *sa;
+    char *hostname;
+    apr_port_t port;
+    hostname = apr_pstrdup(p, lr->bind_addr->hostname);
+    port = lr->bind_addr->port;
+    apr_sockaddr_info_get(&sa, hostname, APR_UNSPEC, port, 0, p);
+    duplr->bind_addr = sa;
+    duplr->next = 0;
+    apr_socket_t *temps;
+    if ((stat = apr_socket_create(&temps, duplr->bind_addr->family,
+                                  SOCK_STREAM, 0, p)) != APR_SUCCESS) {
+        ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, p, APLOGNO(09999)
+                      "ap_duplicate_socket: for address %pI, "
+                      "cannot duplicate a new socket!",
+                      duplr->bind_addr); /*need to fix the APLOGNO */
+        return NULL;
+    }
+    duplr->sd = temps;
+    flag = 1;
+    stat = make_sock(p, duplr);
+/* duplicate from open_listeners()*/
+#if AP_NONBLOCK_WHEN_MULTI_LISTEN
+    use_nonblock = (ap_listeners && ap_listeners->next);
+    if ((stat = apr_socket_opt_set(duplr->sd, APR_SO_NONBLOCK, use_nonblock))
+        != APR_SUCCESS) {
+        ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(09999)
+                      "unable to control socket non-blocking status");
+        return NULL;
+    }  /*need to fix the APLOGNO */
+#endif
+    return duplr;
+}
+
+/* This function is added for the patch. This function duplicates 
+ * open_listeners, alloc_listener() and re-call make_sock() for the 
+ * duplicated listeners. In this function, the newly created sockets
+ * will bind and listen*/
+AP_DECLARE(apr_status_t) ap_post_config_listeners(server_rec *s, apr_pool_t *p,
+                                                  int num_buckets) {
+    mpm_listen = apr_palloc(p, sizeof(ap_listen_rec*) * num_buckets);
+    int i;
+    ap_listen_rec *lr;
+/* duplicate from alloc_listener() for the additional listen record*/
+#ifndef HAVE_SO_REUSEPORT
+    lr = ap_listeners;
+#endif
+    for (i = 0; i < num_buckets; i++) {
+#ifdef HAVE_SO_REUSEPORT
+        ap_listen_rec *templr;
+        lr = ap_listeners;
+        ap_listen_rec *last = NULL;
+        while (lr) {
+            templr = ap_duplicate_listener(p, lr);    
+         
+            ap_apply_accept_filter(p, templr, s);
+            
+            if (last == NULL) {
+                mpm_listen[i] = last = templr;
+            }
+            else {
+                last->next = templr;
+                last = templr;
+            }
+            lr = lr->next;
+        }
+#else
+        mpm_listen[i] = ap_duplicate_listener(p, lr);
+        lr = lr->next;
+#endif
+    }
+    return APR_SUCCESS;
+}
+
 static apr_status_t close_listeners_on_exec(void *v)
 {
     ap_close_listeners();
@@ -585,10 +681,13 @@
 AP_DECLARE_NONSTD(void) ap_close_listeners(void)
 {
     ap_listen_rec *lr;
+    int i;
 
-    for (lr = ap_listeners; lr; lr = lr->next) {
-        apr_socket_close(lr->sd);
-        lr->active = 0;
+    for (i = 0; i < num_buckets; i++) {
+        for (lr = mpm_listen[i]; lr; lr = lr->next) {
+            apr_socket_close(lr->sd);
+            lr->active = 0;
+        }
     }
 }
 AP_DECLARE_NONSTD(int) ap_close_selected_listeners(ap_slave_t *slave)
diff -ru httpd-2.4.7/server/mpm/prefork/prefork.c httpd-2.4.7.new/server/mpm/prefork/prefork.c
--- httpd-2.4.7/server/mpm/prefork/prefork.c	2014-01-24 14:18:13.904893893 -0500
+++ httpd-2.4.7.new/server/mpm/prefork/prefork.c	2014-01-24 14:17:42.244894325 -0500
@@ -48,6 +48,8 @@
 #include "ap_mmn.h"
 #include "apr_poll.h"
 
+#include <stdlib.h>
+
 #ifdef HAVE_TIME_H
 #include <time.h>
 #endif
@@ -86,14 +88,18 @@
 
 /* config globals */
 
-static apr_proc_mutex_t *accept_mutex;
+static apr_proc_mutex_t **accept_mutex;
 static int ap_daemons_to_start=0;
 static int ap_daemons_min_free=0;
 static int ap_daemons_max_free=0;
 static int ap_daemons_limit=0;      /* MaxRequestWorkers */
 static int server_limit = 0;
 static int mpm_state = AP_MPMQ_STARTING;
-static ap_pod_t *pod;
+static ap_pod_t **pod;
+static ap_pod_t *child_pod;
+static apr_proc_mutex_t *child_mutex;
+ap_listen_rec *child_listen;
+int *bucket;	/* bucket array for the httpd child processes */
 
 /* data retained by prefork across load/unload of the module
  * allocated on first call to pre-config hook; located on
@@ -117,7 +123,7 @@
      * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
      * without the need to spawn.
      */
-    int idle_spawn_rate;
+    int idle_spawn_rate[1025];
 #ifndef MAX_SPAWN_RATE
 #define MAX_SPAWN_RATE  (32)
 #endif
@@ -222,14 +228,14 @@
         prefork_note_child_killed(/* slot */ 0, 0, 0);
     }
 
-    ap_mpm_pod_close(pod);
+    ap_mpm_pod_close(child_pod);
     chdir_for_gprof();
     exit(code);
 }
 
 static void accept_mutex_on(void)
 {
-    apr_status_t rv = apr_proc_mutex_lock(accept_mutex);
+    apr_status_t rv = apr_proc_mutex_lock(child_mutex);
     if (rv != APR_SUCCESS) {
         const char *msg = "couldn't grab the accept mutex";
 
@@ -247,7 +253,7 @@
 
 static void accept_mutex_off(void)
 {
-    apr_status_t rv = apr_proc_mutex_unlock(accept_mutex);
+    apr_status_t rv = apr_proc_mutex_unlock(child_mutex);
     if (rv != APR_SUCCESS) {
         const char *msg = "couldn't release the accept mutex";
 
@@ -272,11 +278,10 @@
  * when it's safe in the single Listen case.
  */
 #ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-#define SAFE_ACCEPT(stmt) do {if (ap_listeners->next) {stmt;}} while(0)
+#define SAFE_ACCEPT(stmt) do {if (child_listen->next) {stmt;}} while(0)
 #else
 #define SAFE_ACCEPT(stmt) do {stmt;} while(0)
 #endif
-
 static int prefork_query(int query_code, int *result, apr_status_t *rv)
 {
     *rv = APR_SUCCESS;
@@ -521,10 +526,23 @@
     apr_pool_create(&ptrans, pchild);
     apr_pool_tag(ptrans, "transaction");
 
-    /* needs to be done before we switch UIDs so we have permissions */
+/* close unused listeners and pods */
+    for (i = 0; i < num_buckets; i++) {
+        if (i != bucket[my_child_num]) {
+            lr = mpm_listen[i];
+            while(lr) {
+                apr_socket_close(lr->sd);
+                lr = lr->next;
+            }
+            mpm_listen[i]->active = 0;
+            ap_mpm_pod_close(pod[i]);
+        }
+    }
+
+/* needs to be done before we switch UIDs so we have permissions */
     ap_reopen_scoreboard(pchild, NULL, 0);
-    lockfile = apr_proc_mutex_lockfile(accept_mutex);
-    status = apr_proc_mutex_child_init(&accept_mutex,
+    lockfile = apr_proc_mutex_lockfile(child_mutex);
+    status = apr_proc_mutex_child_init(&child_mutex,
                                        lockfile,
                                        pchild);
     if (status != APR_SUCCESS) {
@@ -532,7 +550,7 @@
                      "Couldn't initialize cross-process lock in child "
                      "(%s) (%s)",
                      lockfile ? lockfile : "none",
-                     apr_proc_mutex_name(accept_mutex));
+                     apr_proc_mutex_name(child_mutex));
         clean_child_exit(APEXIT_CHILDFATAL);
     }
 
@@ -554,7 +572,7 @@
         clean_child_exit(APEXIT_CHILDSICK); /* assume temporary resource issue */
     }
 
-    for (lr = ap_listeners, i = num_listensocks; i--; lr = lr->next) {
+    for (lr = child_listen, i = num_listensocks; i--; lr = lr->next) {
         apr_pollfd_t pfd = { 0 };
 
         pfd.desc_type = APR_POLL_SOCKET;
@@ -612,7 +630,7 @@
 
         if (num_listensocks == 1) {
             /* There is only one listener record, so refer to that one. */
-            lr = ap_listeners;
+            lr = child_listen;
         }
         else {
             /* multiple listening sockets - need to poll */
@@ -710,7 +728,7 @@
          * while we were processing the connection or we are the lucky
          * idle server process that gets to die.
          */
-        if (ap_mpm_pod_check(pod) == APR_SUCCESS) { /* selected as idle? */
+        if (ap_mpm_pod_check(child_pod) == APR_SUCCESS) { /* selected as idle? */
             die_now = 1;
         }
         else if (retained->my_generation !=
@@ -750,7 +768,9 @@
     (void) ap_update_child_status_from_indexes(slot, 0, SERVER_STARTING,
                                                (request_rec *) NULL);
 
-
+    child_listen = mpm_listen[bucket[slot]];
+    child_mutex = accept_mutex[bucket[slot]];
+    child_pod = pod[bucket[slot]];
 #ifdef _OSD_POSIX
     /* BS2000 requires a "special" version of fork() before a setuid() call */
     if ((pid = os_fork(ap_unixd_config.user_name)) == -1) {
@@ -815,20 +835,23 @@
         if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
             continue;
         }
+	bucket[i] = i % num_buckets;
         if (make_child(ap_server_conf, i) < 0) {
             break;
         }
         --number_to_start;
     }
 }
-
-static void perform_idle_server_maintenance(apr_pool_t *p)
+/*
+* patch: execute idle server maintenance on each child group.
+*/
+static void perform_idle_server_maintenance(apr_pool_t *p, int my_bucket)
 {
     int i;
     int idle_count;
     worker_score *ws;
     int free_length;
-    int free_slots[MAX_SPAWN_RATE];
+    int free_slots[MAX_SPAWN_RATE/num_buckets];
     int last_non_dead;
     int total_non_dead;
 
@@ -842,13 +865,13 @@
     for (i = 0; i < ap_daemons_limit; ++i) {
         int status;
 
-        if (i >= retained->max_daemons_limit && free_length == retained->idle_spawn_rate)
+        if (i >= retained->max_daemons_limit && free_length == retained->idle_spawn_rate[my_bucket])
             break;
         ws = &ap_scoreboard_image->servers[i][0];
         status = ws->status;
         if (status == SERVER_DEAD) {
             /* try to keep children numbers as low as possible */
-            if (free_length < retained->idle_spawn_rate) {
+            if (free_length < retained->idle_spawn_rate[my_bucket]) {
                 free_slots[free_length] = i;
                 ++free_length;
             }
@@ -860,7 +883,7 @@
              * So we hopefully won't need to fork more if we count it.
              * This depends on the ordering of SERVER_READY and SERVER_STARTING.
              */
-            if (status <= SERVER_READY) {
+            if ((status <= SERVER_READY) && (bucket[i] == my_bucket)) {
                 ++ idle_count;
             }
 
@@ -869,15 +892,15 @@
         }
     }
     retained->max_daemons_limit = last_non_dead + 1;
-    if (idle_count > ap_daemons_max_free) {
+    if (idle_count > ap_daemons_max_free/num_buckets) {
         /* kill off one child... we use the pod because that'll cause it to
          * shut down gracefully, in case it happened to pick up a request
          * while we were counting
          */
-        ap_mpm_pod_signal(pod);
-        retained->idle_spawn_rate = 1;
+        ap_mpm_pod_signal(pod[my_bucket], my_bucket);
+        retained->idle_spawn_rate[my_bucket] = 1;
     }
-    else if (idle_count < ap_daemons_min_free) {
+    else if (idle_count < ap_daemons_min_free/num_buckets) {
         /* terminate the free list */
         if (free_length == 0) {
             /* only report this condition once */
@@ -887,18 +910,19 @@
                             " raising the MaxRequestWorkers setting");
                 retained->maxclients_reported = 1;
             }
-            retained->idle_spawn_rate = 1;
+            retained->idle_spawn_rate[my_bucket] = 1;
         }
         else {
-            if (retained->idle_spawn_rate >= 8) {
+            if (retained->idle_spawn_rate[my_bucket] >= 8) {
                 ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(00162)
                     "server seems busy, (you may need "
                     "to increase StartServers, or Min/MaxSpareServers), "
                     "spawning %d children, there are %d idle, and "
-                    "%d total children", retained->idle_spawn_rate,
+                    "%d total children", retained->idle_spawn_rate[my_bucket],
                     idle_count, total_non_dead);
             }
             for (i = 0; i < free_length; ++i) {
+		bucket[free_slots[i]] = my_bucket; 
                 make_child(ap_server_conf, free_slots[i]);
             }
             /* the next time around we want to spawn twice as many if this
@@ -907,13 +931,13 @@
             if (retained->hold_off_on_exponential_spawning) {
                 --retained->hold_off_on_exponential_spawning;
             }
-            else if (retained->idle_spawn_rate < MAX_SPAWN_RATE) {
-                retained->idle_spawn_rate *= 2;
+            else if (retained->idle_spawn_rate[my_bucket] < MAX_SPAWN_RATE/num_buckets) {
+                retained->idle_spawn_rate[my_bucket] *= 2;
             }
         }
     }
     else {
-        retained->idle_spawn_rate = 1;
+        retained->idle_spawn_rate[my_bucket] = 1;
     }
 }
 
@@ -926,15 +950,20 @@
     int index;
     int remaining_children_to_start;
     apr_status_t rv;
+    int i;
 
     ap_log_pid(pconf, ap_pid_fname);
 
-    /* Initialize cross-process accept lock */
-    rv = ap_proc_mutex_create(&accept_mutex, NULL, AP_ACCEPT_MUTEX_TYPE, NULL,
-                              s, _pconf, 0);
-    if (rv != APR_SUCCESS) {
-        mpm_state = AP_MPMQ_STOPPING;
-        return DONE;
+    bucket = apr_palloc(_pconf, sizeof(int) *  ap_daemons_limit);
+    /* Initialize cross-process accept lock for each bucket*/
+    accept_mutex = apr_palloc(_pconf, sizeof(apr_proc_mutex_t *) * num_buckets);
+    for (i = 0; i < num_buckets; i++) {
+        rv = ap_proc_mutex_create(&accept_mutex[i], NULL, AP_ACCEPT_MUTEX_TYPE, NULL,
+                                  s, _pconf, 0);
+        if (rv != APR_SUCCESS) {
+            mpm_state = AP_MPMQ_STOPPING;
+            return DONE;
+        }
     }
 
     if (!retained->is_graceful) {
@@ -953,12 +982,13 @@
 
     if (one_process) {
         AP_MONCONTROL(1);
+	bucket[0] = 0;
         make_child(ap_server_conf, 0);
         /* NOTREACHED */
     }
     else {
-    if (ap_daemons_max_free < ap_daemons_min_free + 1)  /* Don't thrash... */
-        ap_daemons_max_free = ap_daemons_min_free + 1;
+    if (ap_daemons_max_free < ap_daemons_min_free + num_buckets)  /* Don't thrash... */
+        ap_daemons_max_free = ap_daemons_min_free + num_buckets;
 
     /* If we're doing a graceful_restart then we're going to see a lot
      * of children exiting immediately when we get into the main loop
@@ -991,7 +1021,7 @@
     ap_log_command_line(plog, s);
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00165)
                 "Accept mutex: %s (default: %s)",
-                apr_proc_mutex_name(accept_mutex),
+                apr_proc_mutex_name(accept_mutex[0]),
                 apr_proc_mutex_defname());
 
     mpm_state = AP_MPMQ_RUNNING;
@@ -1041,7 +1071,7 @@
                     /* child detected a resource shortage (E[NM]FILE, ENOBUFS, etc)
                      * cut the fork rate to the minimum
                      */
-                    retained->idle_spawn_rate = 1;
+                    retained->idle_spawn_rate[bucket[child_slot]] = 1;
                 }
                 else if (remaining_children_to_start
                     && child_slot < ap_daemons_limit) {
@@ -1086,8 +1116,9 @@
              */
             continue;
         }
-
-        perform_idle_server_maintenance(pconf);
+        for (i = 0; i < num_buckets; i++) {
+            perform_idle_server_maintenance(pconf, i);
+        }
     }
     } /* one_process */
 
@@ -1122,7 +1153,9 @@
         ap_close_listeners();
 
         /* kill off the idle ones */
-        ap_mpm_pod_killpg(pod, retained->max_daemons_limit);
+        for (i = 0; i < num_buckets; i++) {
+            ap_mpm_pod_killpg(pod[i], i, retained->max_daemons_limit);
+        }
 
         /* Send SIGUSR1 to the active children */
         active_children = 0;
@@ -1196,8 +1229,9 @@
                     "Graceful restart requested, doing restart");
 
         /* kill off the idle ones */
-        ap_mpm_pod_killpg(pod, retained->max_daemons_limit);
-
+        for (i = 0; i < num_buckets; i++) {
+            ap_mpm_pod_killpg(pod[i], i, retained->max_daemons_limit);
+        }
         /* This is mostly for debugging... so that we know what is still
          * gracefully dealing with existing request.  This will break
          * in a very nasty way if we ever have the scoreboard totally
@@ -1238,6 +1272,9 @@
 {
     int startup = 0;
     int level_flags = 0;
+    int i;
+    int num_of_cores = 0;
+    ap_listen_rec *lr;
     apr_status_t rv;
 
     pconf = p;
@@ -1248,18 +1285,41 @@
         level_flags |= APLOG_STARTUP;
     }
 
+    flag = 0; /* do not bind and listen to ap_listeners */
     if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {
         ap_log_error(APLOG_MARK, APLOG_ALERT | level_flags, 0,
                      (startup ? NULL : s),
                      "no listening sockets available, shutting down");
         return DONE;
     }
-
-    if ((rv = ap_mpm_pod_open(pconf, &pod))) {
-        ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
-                     (startup ? NULL : s),
-                     "could not open pipe-of-death");
-        return DONE;
+#ifdef HAVE_SO_REUSEPORT
+    num_of_cores = sysconf(_SC_NPROCESSORS_ONLN);
+    if (num_of_cores > 8) {
+        num_buckets = sysconf(_SC_NPROCESSORS_ONLN)/8;
+    }
+    else {
+        num_buckets = 1;
+    }
+#else
+    if (num_listensocks > 1) {
+        num_buckets = num_listensocks;
+        num_listensocks = 1; /* partition the listener into different bucket */
+    }        
+#endif
+    ap_post_config_listeners(ap_server_conf, pconf, num_buckets);
+
+    for (lr = ap_listeners; lr; lr=lr->next) {
+        apr_socket_close(lr->sd);
+    }
+
+    pod = apr_palloc(pconf, sizeof(ap_pod_t *) * num_buckets);
+    for (i = 0; i < num_buckets; i++) {   
+        if ((rv = ap_mpm_pod_open(pconf, &pod[i]))) {
+            ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
+                         (startup ? NULL : s),
+                         "could not open pipe-of-death");
+            return DONE;
+        }
     }
     return OK;
 }
@@ -1292,7 +1352,10 @@
     if (!retained) {
         retained = ap_retained_data_create(userdata_key, sizeof(*retained));
         retained->max_daemons_limit = -1;
-        retained->idle_spawn_rate = 1;
+        int i;
+        for (i = 0; i < 1025; i++) {
+            retained->idle_spawn_rate[i] = 1;
+        }
     }
     ++retained->module_loads;
     if (retained->module_loads == 2) {
diff -ru httpd-2.4.7/server/mpm_unix.c httpd-2.4.7.new/server/mpm_unix.c
--- httpd-2.4.7/server/mpm_unix.c	2014-01-24 14:18:13.810893894 -0500
+++ httpd-2.4.7.new/server/mpm_unix.c	2014-01-24 14:17:42.132894326 -0500
@@ -607,7 +607,7 @@
  * permits the MPM to skip the poll when there is only one listening
  * socket, because it provides a alternate way to unblock an accept()
  * when the pod is used.  */
-static apr_status_t dummy_connection(ap_pod_t *pod)
+static apr_status_t dummy_connection(ap_pod_t *pod, int my_bucket)
 {
     const char *data;
     apr_status_t rv;
@@ -626,12 +626,12 @@
      * plain-HTTP, not SSL; using an SSL port would either be
      * expensive to do correctly (performing a complete SSL handshake)
      * or cause log spam by doing incorrectly (simply sending EOF). */
-    lp = ap_listeners;
+    lp = mpm_listen[my_bucket];
     while (lp && lp->protocol && strcasecmp(lp->protocol, "http") != 0) {
         lp = lp->next;
     }
     if (!lp) {
-        lp = ap_listeners;
+        lp = mpm_listen[my_bucket];
     }
 
     rv = apr_socket_create(&sock, lp->bind_addr->family, SOCK_STREAM, 0, p);
@@ -712,19 +712,20 @@
     return rv;
 }
 
-AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod)
+AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod, int my_bucket)
 {
     apr_status_t rv;
+    int i;
 
     rv = pod_signal_internal(pod);
     if (rv != APR_SUCCESS) {
         return rv;
     }
-
-    return dummy_connection(pod);
+    
+    return dummy_connection(pod, my_bucket);
 }
 
-void ap_mpm_pod_killpg(ap_pod_t *pod, int num)
+void ap_mpm_pod_killpg(ap_pod_t *pod, int my_bucket, int num)
 {
     int i;
     apr_status_t rv = APR_SUCCESS;
@@ -742,8 +743,9 @@
      * readers stranded (a number of them could be tied up for
      * a while serving time-consuming requests)
      */
+
     for (i = 0; i < num && rv == APR_SUCCESS; i++) {
-        rv = dummy_connection(pod);
+        rv = dummy_connection(pod, my_bucket);
     }
 }
 
