Index: hotplug2-0.9/hotplug2.c
===================================================================
--- hotplug2-0.9.orig/hotplug2.c	2008-08-04 10:02:27.000000000 +0200
+++ hotplug2-0.9/hotplug2.c	2008-08-04 10:03:04.000000000 +0200
@@ -21,6 +21,7 @@
 #include <sys/mman.h>
 #include <linux/types.h>
 #include <linux/netlink.h>
+#include <poll.h>
 
 #include "mem_utils.h"
 #include "filemap_utils.h"
@@ -492,6 +493,11 @@
 	char *coldplug_command = NULL;
 	char *rules_file = HOTPLUG2_RULE_PATH;
 	sigset_t block_mask;
+	struct pollfd msg_poll;
+
+	struct hotplug2_event_t *backlog = NULL;
+	struct hotplug2_event_t *backlog_tail = NULL;
+	int n_backlog = 0;
 	
 	struct rules_t *rules = NULL;
 	struct filemap_t filemap;
@@ -602,6 +608,8 @@
 	 * Open netlink socket to read the uevents
 	 */
 	netlink_socket = init_netlink_socket(NETLINK_BIND);
+	msg_poll.fd = netlink_socket;
+	msg_poll.events = POLLIN;
 	
 	if (netlink_socket == -1) {
 		ERROR("netlink init","Unable to open netlink socket.");
@@ -642,20 +650,44 @@
 	 * Main loop reading uevents
 	 */
 	while (!terminate) {
-		/*
-		 * Read the uevent packet
-		 */
-		size = recv(netlink_socket, &buffer, sizeof(buffer), 0);
-		recv_errno = errno;
+		if ((n_backlog > 0) && (child_c < max_child_c)) {
+			/* dequeue backlog message */
+			tmpevent = backlog;
+			backlog = backlog->next;
+			n_backlog--;
+			if (backlog_tail == tmpevent)
+				backlog_tail = NULL;
+		} else {
+			/*
+			 * Read the uevent packet
+			 */
+			if (n_backlog >= HOTPLUG2_MSG_BACKLOG) {
+				usleep(HOTPLUG2_THROTTLE_INTERVAL * 1000);
+				continue;
+			}
+
+			if ((n_backlog > 0) && (child_c >= max_child_c)) {
+				int fds;
+				msg_poll.revents = 0;
+				fds = poll(&msg_poll, 1, HOTPLUG2_THROTTLE_INTERVAL);
+				if (fds < 0) {
+					continue;
+				}
+				if (fds == 0)
+					continue;
+			}
+			size = recv(netlink_socket, &buffer, sizeof(buffer), 0);
+			recv_errno = errno;
 	
-		/*
-		 * Parse the event into an event structure
-		 */
-		tmpevent = get_hotplug2_event(buffer, size);
+			/*
+			 * Parse the event into an event structure
+			 */
+			tmpevent = get_hotplug2_event(buffer, size);
 		
-		if (tmpevent == NULL) {
-			ERROR("reading events", "Malformed event read (missing action prefix).");
-			continue;
+			if (tmpevent == NULL) {
+				ERROR("reading events", "Malformed event read (missing action prefix).");
+				continue;
+			}
 		}
 		
 		/*
@@ -706,13 +738,16 @@
 			 * Unless, of course, we've specified otherwise and no rules that match
 			 * need throttling.
 			 */
-			if (!flags & FLAG_NOTHROTTLE) {
-				/*
-				 * Okay, throttle away!
-				 */
-				while (child_c >= max_child_c) {
-					usleep(HOTPLUG2_THROTTLE_INTERVAL);
-				}
+			if (!(flags & FLAG_NOTHROTTLE) && (child_c >= max_child_c)) {
+				/* log the packet and process it later */
+				if (backlog_tail)
+					backlog_tail->next = tmpevent;
+				else
+					backlog = tmpevent;
+				tmpevent->next = NULL;
+				backlog_tail = tmpevent;
+				n_backlog++;
+				continue;
 			}
 			
 			sigemptyset(&block_mask);
Index: hotplug2-0.9/hotplug2.h
===================================================================
--- hotplug2-0.9.orig/hotplug2.h	2008-08-04 10:02:27.000000000 +0200
+++ hotplug2-0.9/hotplug2.h	2008-08-04 10:02:27.000000000 +0200
@@ -45,9 +45,9 @@
 #define DBG(action, fmt, arg...)
 #endif
 
+#define HOTPLUG2_MSG_BACKLOG	64
 #define UEVENT_BUFFER_SIZE		2048
-#define HOTPLUG2_POLL_INTERVAL		20000
-#define HOTPLUG2_THROTTLE_INTERVAL	10000
+#define HOTPLUG2_THROTTLE_INTERVAL	50
 #define HOTPLUG2_RULE_PATH		"/etc/hotplug2.rules"
 
 #define ACTION_ADD			0
@@ -76,6 +76,7 @@
 	int env_vars_c;
 	char *plain;
 	int plain_s;
+	struct hotplug2_event_t *next;
 };
 
 struct options_t {
