diff -ur -x '*.o' nagios-2-x-cvs/base/commands.c nagios-sr/base/commands.c
--- nagios-2-x-cvs/base/commands.c	2005-12-23 20:31:36.000000000 +0100
+++ nagios-sr/base/commands.c	2007-04-12 14:12:30.000000000 +0200
@@ -32,6 +32,8 @@
 #include "../include/broker.h"
 #include "../include/nagios.h"
 
+#include <search.h>
+
 extern char     *config_file;
 extern char	*log_file;
 extern char     *command_file;
@@ -83,6 +85,11 @@
 passive_check_result    *passive_check_result_list=NULL;
 passive_check_result    *passive_check_result_list_tail=NULL;
 
+static void *passive_check_result_tree = NULL;
+static pthread_mutex_t passive_check_result_mtx;
+static pthread_cond_t passive_check_result_cond;
+
+
 extern pthread_t       worker_threads[TOTAL_WORKER_THREADS];
 extern circular_buffer external_command_buffer;
 
@@ -586,11 +593,6 @@
 
 	        }
 
-	/**** PROCESS ALL PASSIVE SERVICE CHECK RESULTS AT ONE TIME ****/
-	if(passive_check_result_list!=NULL)
-		process_passive_service_checks();
-
-
 #ifdef DEBUG0
 	printf("check_for_external_commands() end\n");
 #endif
@@ -1786,6 +1788,14 @@
 
 
 
+static int pcr_compare(const void *a, const void *b) {
+	const passive_check_result *pcr_a = a;
+	const passive_check_result *pcr_b = b;
+	int r = strcmp(pcr_a->host_name, pcr_b->host_name);
+	if (!r) r = strcmp(pcr_a->svc_description, pcr_b->svc_description);
+	return r;
+}
+
 /* submits a passive service check result for later processing */
 int process_passive_service_check(time_t check_time, char *host_name, char *svc_description, int return_code, char *output){
 	passive_check_result *new_pcr=NULL;
@@ -1869,12 +1879,28 @@
 
 	new_pcr->next=NULL;
 
-	/* add the passive check result to the end of the list in memory */
-	if(passive_check_result_list==NULL)
+	pthread_mutex_lock(&passive_check_result_mtx);
+	if(passive_check_result_list==NULL) { /* No pending results */
+		passive_check_result *tree_pcr;
 		passive_check_result_list=new_pcr;
-	else
-		passive_check_result_list_tail->next=new_pcr;
-	passive_check_result_list_tail=new_pcr;
+		passive_check_result_list_tail=new_pcr;
+		tsearch(new_pcr, &passive_check_result_tree, pcr_compare);
+		pthread_cond_signal(&passive_check_result_cond);
+	} else { /* Duplicate detection */
+		passive_check_result *tree_pcr = *(void **)tsearch(new_pcr, &passive_check_result_tree, pcr_compare);
+		if (tree_pcr != new_pcr) { /* replace entry */
+			free(tree_pcr->host_name); tree_pcr->host_name = new_pcr->host_name;
+			free(tree_pcr->svc_description); tree_pcr->svc_description = new_pcr->svc_description;
+			tree_pcr->return_code = new_pcr->return_code;
+			free(tree_pcr->output); tree_pcr->output = new_pcr->output;
+			tree_pcr->check_time = new_pcr->check_time;
+			free(new_pcr);
+		} else {
+			passive_check_result_list_tail->next=new_pcr;
+			passive_check_result_list_tail=new_pcr;
+		}
+	}
+	pthread_mutex_unlock(&passive_check_result_mtx);
 
 #ifdef DEBUG0
 	printf("process_passive_service_check() end\n");
@@ -4423,104 +4449,125 @@
         }
 
 
-/* process all passive service checks found in a given file */
-void process_passive_service_checks(void){
+/* process all passive service checks */
+static void free_passive_check_result(passive_check_result *pcr) {
+	free(pcr->host_name);
+	free(pcr->svc_description);
+	free(pcr->output);
+	free(pcr);
+}
+
+
+static void cleanup_process_passive_service_check_thread(void *arg) {
+	while(passive_check_result_list) {
+		passive_check_result *temp_pcr = passive_check_result_list;
+		passive_check_result_list = temp_pcr->next;
+		tdelete(temp_pcr, &passive_check_result_tree, pcr_compare);
+		free_passive_check_result(temp_pcr);
+	}
+	passive_check_result_list_tail = NULL;
+	pthread_mutex_unlock(&passive_check_result_mtx); /* possibly canceled while waiting for passive_check_result_cond */
+}
+
+
+void *process_passive_service_check_thread(void *arg){
 	service_message svc_msg;
-	pid_t pid;
 	passive_check_result *temp_pcr;
-	passive_check_result *this_pcr;
-	passive_check_result *next_pcr;
 
+	pthread_cleanup_push(cleanup_process_passive_service_check_thread, NULL);
 
-#ifdef DEBUG0
-	printf("process_passive_service_checks() start\n");
-#endif
+	pthread_mutex_lock(&passive_check_result_mtx);
+	for(;;) {
+		while (!passive_check_result_list)
+			pthread_cond_wait(&passive_check_result_cond, &passive_check_result_mtx);
 
-	/* fork... */
-	pid=fork();
+		temp_pcr = passive_check_result_list;
+		passive_check_result_list = temp_pcr->next;
+		tdelete(temp_pcr, &passive_check_result_tree, pcr_compare);
+		if (!passive_check_result_list) passive_check_result_list_tail = NULL;
 
-	/* an error occurred while trying to fork */
-	if(pid==-1)
-		return;
+		pthread_mutex_unlock(&passive_check_result_mtx);
 
-	/* if we are in the child process... */
-	if(pid==0){
+		strncpy(svc_msg.host_name,temp_pcr->host_name,sizeof(svc_msg.host_name)-1);
+		svc_msg.host_name[sizeof(svc_msg.host_name)-1]='\x0';
+		strncpy(svc_msg.description,temp_pcr->svc_description,sizeof(svc_msg.description)-1);
+		svc_msg.description[sizeof(svc_msg.description)-1]='\x0';
+		snprintf(svc_msg.output,sizeof(svc_msg.output)-1,"%s",temp_pcr->output);
+ 		svc_msg.output[sizeof(svc_msg.output)-1]='\x0';
+		svc_msg.return_code=temp_pcr->return_code;
+		svc_msg.parallelized=FALSE;
+		svc_msg.exited_ok=TRUE;
+		svc_msg.check_type=SERVICE_CHECK_PASSIVE;
+		svc_msg.start_time.tv_sec=temp_pcr->check_time;
+		svc_msg.start_time.tv_usec=0;
+		svc_msg.finish_time=svc_msg.start_time;
 
-		/* become the process group leader */
-		setpgid(0,0);
+		free_passive_check_result(temp_pcr);
 
-		/* free allocated memory */
-		free_memory();
+		/* write the service check results... */
+		write_svc_message(&svc_msg);
 
-		/* close read end of IPC pipe */
-		close(ipc_pipe[0]);
-
-		/* reset signal handling */
-		reset_sighandler();
-
-		/* fork again... */
-		pid=fork();
-
-		/* the grandchild process should submit the service check result... */
-		if(pid==0){
-
-			/* write all service checks to the IPC pipe for later processing by the grandparent */
-			for(temp_pcr=passive_check_result_list;temp_pcr!=NULL;temp_pcr=temp_pcr->next){
-
-				strncpy(svc_msg.host_name,temp_pcr->host_name,sizeof(svc_msg.host_name)-1);
-				svc_msg.host_name[sizeof(svc_msg.host_name)-1]='\x0';
-				strncpy(svc_msg.description,temp_pcr->svc_description,sizeof(svc_msg.description)-1);
-				svc_msg.description[sizeof(svc_msg.description)-1]='\x0';
-				snprintf(svc_msg.output,sizeof(svc_msg.output)-1,"%s",temp_pcr->output);
-				svc_msg.output[sizeof(svc_msg.output)-1]='\x0';
-				svc_msg.return_code=temp_pcr->return_code;
-				svc_msg.parallelized=FALSE;
-				svc_msg.exited_ok=TRUE;
-				svc_msg.check_type=SERVICE_CHECK_PASSIVE;
-				svc_msg.start_time.tv_sec=temp_pcr->check_time;
-				svc_msg.start_time.tv_usec=0;
-				svc_msg.finish_time=svc_msg.start_time;
+		pthread_testcancel();
 
-				/* write the service check results... */
-				write_svc_message(&svc_msg);
-	                        }
-		        }
+		pthread_mutex_lock(&passive_check_result_mtx);
+	}
+	pthread_mutex_unlock(&passive_check_result_mtx);
 
-		/* free memory for the passive service check result list */
-		this_pcr=passive_check_result_list;
-		while(this_pcr!=NULL){
-			next_pcr=this_pcr->next;
-			free(this_pcr->host_name);
-			free(this_pcr->svc_description);
-			free(this_pcr->output);
-			free(this_pcr);
-			this_pcr=next_pcr;
-	                }
+	pthread_cleanup_pop(1); /* macro idiocy */
 
-		exit(OK);
-	        }
+	return NULL;
+}
 
-	/* else the parent should wait for the first child to return... */
-	else if(pid>0)
-		waitpid(pid,NULL,0);
-
-	/* free memory for the passive service check result list */
-	this_pcr=passive_check_result_list;
-	while(this_pcr!=NULL){
-		next_pcr=this_pcr->next;
-		free(this_pcr->host_name);
-		free(this_pcr->svc_description);
-		free(this_pcr->output);
-		free(this_pcr);
-		this_pcr=next_pcr;
-	        }
-	passive_check_result_list=NULL;
-	passive_check_result_list_tail=NULL;
 
-#ifdef DEBUG0
-	printf("process_passive_service_checks() end\n");
+int init_process_passive_service_check_thread(void){
+	int result;
+	sigset_t newmask;
+
+	/* new thread should block all signals */
+	sigfillset(&newmask);
+	pthread_sigmask(SIG_BLOCK,&newmask,NULL);
+
+	/* Mutexes, Condition var */
+	pthread_mutex_init(&passive_check_result_mtx, NULL);
+	pthread_cond_init(&passive_check_result_cond, NULL);
+
+	/* create worker thread */
+	result=pthread_create(&worker_threads[PASSIVE_SENDER_THREAD],NULL,process_passive_service_check_thread,NULL);
+
+	/* main thread should unblock all signals */
+	pthread_sigmask(SIG_UNBLOCK,&newmask,NULL);
+
+#ifdef DEBUG1
+	printf("PASSIVE SENDER THREAD: %lu\n",(unsigned long)worker_threads[PASSIVE_SENDER_THREAD]);
 #endif
 
-	return;
-        }
+	if(result)
+		return ERROR;
+
+	return OK;
+}
+
+
+/* shutdown command file worker thread. This is also called on
+ * sigrestart. Currently, Nagios throws away all pending service
+ * check results by closing and reopening its' internal ipc_pipe.
+ * We'll mimic this behaviour by shutting down the worker thread
+ * and clearing pending entries in
+ * cleanup_process_passive_service_check_thread(). This is done
+ * without taking pthread_mutex_destroy and assumes that nobody
+ * check_for_external_commands() during shutdown/restart.
+ */
+int shutdown_process_passive_service_check_thread(void){
+	/* tell the worker thread to exit */
+	pthread_cancel(worker_threads[PASSIVE_SENDER_THREAD]);
+
+	/* wait for the worker thread to exit */
+	pthread_join(worker_threads[PASSIVE_SENDER_THREAD],NULL);
+
+	/* Free condition/mutex resources */
+	pthread_cond_destroy(&passive_check_result_cond);
+	pthread_mutex_destroy(&passive_check_result_mtx);
+
+	return OK;
+}
 
diff -ur -x '*.o' nagios-2-x-cvs/base/nagios.c nagios-sr/base/nagios.c
--- nagios-2-x-cvs/base/nagios.c	2006-07-13 23:57:33.000000000 +0200
+++ nagios-sr/base/nagios.c	2007-04-10 12:31:37.000000000 +0200
@@ -697,6 +697,22 @@
 				exit(ERROR);
 		                }
 
+			result=init_process_passive_service_check_thread();
+			if(result!=OK){
+
+				snprintf(buffer,sizeof(buffer),"Bailing out due to errors encountered while trying to initialize passive service check thread... (PID=%d)\n",(int)getpid());
+				buffer[sizeof(buffer)-1]='\x0';
+				write_to_logs_and_console(buffer,NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR ,TRUE);
+
+#ifdef USE_EVENT_BROKER
+				/* send program data to broker */
+				broker_program_state(NEBTYPE_PROCESS_SHUTDOWN,NEBFLAG_PROCESS_INITIATED,NEBATTR_SHUTDOWN_ABNORMAL,NULL);
+#endif
+				cleanup();
+				exit(ERROR);
+		                }
+
+
 			/* reset the restart flag */
 			sigrestart=FALSE;
 
@@ -746,6 +762,7 @@
 				deinit_embedded_perl();
 
 			/* cleanup worker threads */
+			shutdown_process_passive_service_check_thread();
 			shutdown_service_result_worker_thread();
 
 			/* shutdown stuff... */
diff -ur -x '*.o' nagios-2-x-cvs/base/utils.c nagios-sr/base/utils.c
--- nagios-2-x-cvs/base/utils.c	2007-03-29 17:02:06.000000000 +0200
+++ nagios-sr/base/utils.c	2007-04-10 16:58:34.000000000 +0200
@@ -3853,17 +3853,11 @@
 
 		if(write_result==-1){
 
-			/* pipe is full - wait a bit and retry */
-			if(errno==EAGAIN){
-				tv.tv_sec=0;
-				tv.tv_usec=250;
-				select(0,NULL,NULL,NULL,&tv);
-				continue;
-			        }
-
 			/* an interrupt occurred - retry */
-			if(errno==EINTR)
+			if(errno==EINTR){
+				pthread_testcancel(); /* LinuxThreads workaround */
 				continue;
+				}
 
 			/* some other error occurred - bail out */
 			break;
@@ -3916,8 +3910,8 @@
 		        }
 	        }
 
-	/* open the command file for reading (non-blocked) - O_TRUNC flag cannot be used due to errors on some systems */
-	if((command_file_fd=open(command_file,O_RDONLY | O_NONBLOCK))<0){
+	/* open the command file for RW to avoid EOF condition */
+	if((command_file_fd=open(command_file,O_RDWR | O_NONBLOCK))<0){
 
 		snprintf(buffer,sizeof(buffer)-1,"Error: Could not open external command file for reading via open(): (%d) -> %s\n",errno,strerror(errno));
 		buffer[sizeof(buffer)-1]='\x0';
@@ -4931,6 +4925,8 @@
 void * command_file_worker_thread(void *arg){
 	char input_buffer[MAX_INPUT_BUFFER];
 	struct timeval tv;
+	fd_set fds;
+	int fd;
 	int buffer_items;
 	int result;
 
@@ -4941,16 +4937,26 @@
 	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
 	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
 
+	FD_ZERO(&fds);
+	fd = fileno(command_file_fp);
+
 	while(1){
 
 		/* should we shutdown? */
 		pthread_testcancel();
 
-		/**** POLL() AND SELECT() DON'T SEEM TO WORK ****/
-		/* wait a bit */
+		/* Hack: avoid endless loop when there are not enough buffers
+		 * to read all data. Normally, submit_external_command() should
+		 * signal back, but....
+		 */
 		tv.tv_sec=0;
 		tv.tv_usec=500000;
-		select(0,NULL,NULL,NULL,&tv);
+		if(buffer_items<external_command_buffer_slots) {
+			FD_SET(fd, &fds);
+			select(fd+1,&fds,NULL,NULL,&tv);
+		} else {
+			select(0,NULL,NULL,NULL,&tv);
+		}
 
 		/* should we shutdown? */
 		pthread_testcancel();
diff -ur -x '*.o' nagios-2-x-cvs/include/nagios.h.in nagios-sr/include/nagios.h.in
--- nagios-2-x-cvs/include/nagios.h.in	2006-10-27 02:06:42.000000000 +0200
+++ nagios-sr/include/nagios.h.in	2007-04-10 12:31:37.000000000 +0200
@@ -483,10 +483,11 @@
 #define SERVICE_BUFFER_SLOTS		  1024
 
 /* worker threads */
-#define TOTAL_WORKER_THREADS              2
+#define TOTAL_WORKER_THREADS              3
 
 #define COMMAND_WORKER_THREAD		  0
 #define SERVICE_WORKER_THREAD  		  1
+#define PASSIVE_SENDER_THREAD		  2
 
 
 /******************** FUNCTIONS **********************/
@@ -728,7 +729,10 @@
 void disable_service_freshness_checks(void);		/* disable service freshness checks */
 void enable_host_freshness_checks(void);		/* enable host freshness checks */
 void disable_host_freshness_checks(void);		/* disable host freshness checks */
-void process_passive_service_checks(void);              /* processes passive service check results */
+
+int init_process_passive_service_check_thread(void);
+int shutdown_process_passive_service_check_thread(void);
+
 void enable_all_failure_prediction(void);               /* enables failure prediction on a program-wide basis */
 void disable_all_failure_prediction(void);              /* disables failure prediction on a program-wide basis */
 void enable_performance_data(void);                     /* enables processing of performance data on a program-wide basis */
