diff -ruN --exclude=CVS aspseek.old/etc/searchd.conf-dist.in aspseek/etc/searchd.conf-dist.in
--- aspseek.old/etc/searchd.conf-dist.in	Wed Jul 24 22:33:47 2002
+++ aspseek/etc/searchd.conf-dist.in	Wed Apr 14 22:48:41 2004
@@ -105,6 +105,11 @@
 # Default value is 10
 #MaxThreads 20
 
+############################################################################
+# MaxIdleTime <N>
+# Maximum number of seconds threads will idle before dying off.
+# Default value is 60
+#MaxIdleTime 600
 
 ############################################################################
 # Include <filename>
diff -ruN --exclude=CVS aspseek.old/include/daemon.h aspseek/include/daemon.h
--- aspseek.old/include/daemon.h	Tue May 14 21:47:15 2002
+++ aspseek/include/daemon.h	Wed Apr 14 22:46:49 2004
@@ -70,9 +55,10 @@
 	CEvent m_req;			///< CEvent object, posted on request
 	pthread_t m_thread;		///< Thread ID
 	int m_socket;			///< Socket returned by accept
+	int m_removed;			///< object has been removed from the linked list
 	CSQLDatabase* m_database;	///< Database associated with thread
 	CWorkerThread* m_next;		///< Next CWorkerThread in the linked list of threads
-	CWorkerThread** m_prev;		///< Pointer to the location of pointer to this CWorkerThread in the preivious object linked list of threads
+	CWorkerThread* m_prev;		///< Previous CWorkerThread in the linked list of threads
 	CWorkerThreadList* m_parent;	///< Pointer to the linked list object holding worker threads
 
 public:
@@ -81,25 +67,23 @@
 		m_next = NULL;
 		m_prev = NULL;
 		m_parent = NULL;
+		m_database = NULL;
 		m_thread = 0;
 		m_socket = 0;
+		m_removed = 0;
 	}
-	/// This method removes current object from linked list
-	CWorkerThread* Remove()
-	{
-		if (m_prev)
-		{
-			*m_prev = m_next;
-		}
-		return this;
-	}
-	/// This method inserts current object after specified in the linked list
-	void Insert(CWorkerThread** prev)
+	~CWorkerThread()
 	{
-		m_next = *prev;
-		m_prev = prev;
-		*m_prev = this;
+		m_prev = NULL;
+		m_next = NULL;
+		m_parent = NULL;
+		m_database = NULL;
+		m_thread = 0;
+		m_socket = 0;
+		m_removed = 1;
 	}
+	CWorkerThread* Remove();
+	void Insert(CWorkerThread* prev);
 };
 
 #define MAX_WAITING_SOCKETS 1024
@@ -153,6 +137,40 @@
 	/// Process incoming request, source of request is socket "csock"
 	void processReq(CSQLDatabase* database, int csock);
 };
+
+	/// This method inserts current object after specified in the linked list
+	inline void CWorkerThread::Insert(CWorkerThread* prev)
+	{
+		m_next = prev->m_next;
+		if(prev->m_next)
+			prev->m_next->m_prev = this;
+		prev->m_next = this;
+		m_prev = prev;
+		m_removed = 0;
+	}
+	/// This method removes current object from linked list
+	inline CWorkerThread* CWorkerThread::Remove()
+	{
+		
+		if(m_next)
+		{
+			if(m_parent->m_first == this)
+				m_parent->m_first = m_next;
+			m_next->m_prev = m_prev;
+		}
+		if(m_prev)
+		{
+			if(m_parent->m_first == this)
+				m_parent->m_first = m_prev;
+			m_prev->m_next = m_next;
+		}
+		else if(!m_next)
+			m_parent->m_first = NULL;
+		m_prev = NULL;
+		m_next = NULL;
+		m_removed = 1;
+		return this;
+	}
 
 /** Auxiliary class for simple mutex locking.
  * Locks mutex, specified by parameter of constructor, and unlocks it
diff -ruN --exclude=CVS aspseek.old/man/searchd.conf.5.ep.in aspseek/man/searchd.conf.5.ep.in
--- aspseek.old/man/searchd.conf.5.ep.in	Mon Jan 13 21:15:16 2003
+++ aspseek/man/searchd.conf.5.ep.in	Wed Apr 14 22:46:58 2004
@@ -13,7 +13,7 @@
 \fBDBAddr\fR \fBDBType\fR:[//[\fBUser\fR[:\fBPass\fR]@]\fBHost\fR[:\fBPort\fR]]/\fBDBName\fR/
 Defines SQL server connection parameters.
 .br
-\fBDBType\fR is SQL server type, it can be \fImysql\fR or \fIoracle8\fR
+\fBDBType\fR is SQL server type, it can be \fImysql\fR or \fIPostgreSQL\fR
 for now.
 .br
 \fBUser\fR is a SQL server's user to connect as.
@@ -68,6 +68,10 @@
 to process queries. Setting high value can result in big memory consumption.
 Setting low value can result in big response time for queries in high load
 conditions (as "extra" queries are queued). Default value is \fI10\fR.
+.TP
+\fBMaxIdleTime\fR \fInum\fR
+Sets the time in seconds that each thread will idle before dying off.
+Default value is \fI60\fR seconds.
 .TP
 \fBMultipleDBConnections\fR \fIyes\fR | \fIno\fR
 Sets whether to use separate connection to the database for each thread.
diff -ruN --exclude=CVS aspseek.old/src/daemon.cpp aspseek/src/daemon.cpp
--- aspseek.old/src/daemon.cpp	Tue Mar 23 04:36:20 2004
+++ aspseek/src/daemon.cpp	Wed Apr 14 22:46:41 2004
@@ -31,6 +31,7 @@
 #include <unistd.h>
 #include <dlfcn.h>
 #include <string.h>
+#include <time.h>
 #include <string>
 #include <vector>
 #include "sqldb.h"
@@ -76,6 +77,7 @@
 #include "cache.h"
 
 int MaxThreads = 10;
+int max_idle_time = 60;
 string ConfDir = CONF_DIR;
 string DataDir = DATA_DIR;
 
@@ -445,6 +447,10 @@
 			{
 				MaxThreads = atoi(Trim(str + 10, "= \t\r\n"));
 			}
+			else if (!STRNCASECMP(str, "MaxIdleTime"))
+			{
+					max_idle_time = atoi(Trim(str + 11, "= \t\r\n"));
+			}
 			else if (!STRNCASECMP(str, "DebugLevel"))
 			{
 				logger.setloglevel(Trim(str + 10, "= \t\r\n"));
@@ -1068,33 +1074,59 @@
 void* processReqs(void* p)
 {
 	CWorkerThread* thread = (CWorkerThread*)p;
+	time_t last_query = time(NULL);
+	int timeout = 0;
+	thread->m_parent->m_threads++;
 	while (doit_forever)
 	{
 		// Wait for event, posted in CWorkerThreadList::processReq
-		thread->m_req.Wait();
-		// Create search context
-		CSearchContext ctx(thread->m_database, thread->m_socket);
-		while (doit_forever)
-		{
-			// Process one query
-			processReq1(&ctx);
-			ctx.m_socket.Close();
-			{
-				CLocker lock(&thread->m_parent->m_mutex);
-				if (thread->m_parent->IsWaiting())
-				{
-					// Process other queries in the loop buffer
-					ctx.m_socket = thread->m_parent->PopFirstWaiting();
-				}
-				else
+		timeout = thread->m_req.Wait(1000);
+		if(!timeout)
+		{
+			time(&last_query);
+			// Create search context
+			CSearchContext ctx(thread->m_database, thread->m_socket);
+			while (doit_forever)
+			{
+				// Process one query
+				processReq1(&ctx);
+				ctx.m_socket.Close();
 				{
-					// Make thread available for other requests
-					thread->Insert(&thread->m_parent->m_first);
-					break;
+					CLocker lock(&thread->m_parent->m_mutex);
+					if (thread->m_parent->IsWaiting())
+					{
+						// Process other queries in the loop buffer
+						ctx.m_socket = thread->m_parent->PopFirstWaiting();
+					}
+					else
+					{
+						// Make thread available for other requests
+						if(!thread->m_parent->m_first)
+							thread->m_parent->m_first = thread;
+							//thread->Insert(thread);
+						else
+							thread->Insert(thread->m_parent->m_first);
+						break;
+					}
 				}
 			}
 		}
+		else
+		{
+			if((time(NULL) - last_query) > max_idle_time)
+				break;
+		}
 	}
+	// create scope for CLocker
+	{
+		CLocker lock(&thread->m_parent->m_mutex);
+		if(!thread->m_removed)
+			thread->Remove();
+	}
+	// unlocked and removed...
+	if(MultiDBConnections)
+		thread->m_database->CloseDb();
+	thread->m_parent->m_threads--;
 	delete thread;
 	return NULL; // to make g++ happy
 }
@@ -1130,7 +1162,6 @@
 			if (thread_stack_size)
 				pthread_attr_setstacksize(&attr, thread_stack_size);
 			pthread_create(&thread->m_thread, &attr, processReqs, thread);
-			m_threads++;
 		}
 		else
 		{
@@ -1141,7 +1172,6 @@
 	}
 	else
 	{
-		// Remove first worker thread from the linked list
 		thread = m_first->Remove();
 	}
 	thread->m_socket = csock;
@@ -1175,11 +1205,26 @@
 		logger.log(CAT_NET, L_ERR, "Error %d in socket(): %s\n", errno, strerror(errno));
 		return 4;
 	}
-	int rc = bind(sock, (struct sockaddr*)&addr, sizeof(addr));
-	if (rc < 0)
+	int x = 1;
+	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &x, sizeof(x));
+	int retrycount = 0;
+	int rc;
+	while(retrycount < 5)
 	{
-		logger.log(CAT_NET, L_ERR, "Error %d in bind(): %s\n", errno, strerror(errno));
-		return 5;
+		rc = bind(sock, (struct sockaddr*)&addr, sizeof(addr));
+		if (rc < 0 && retrycount >= 5)
+		{
+			logger.log(CAT_NET, L_ERR, "Error %d in bind(): %s\n", errno, strerror(errno));
+			return 5;
+		}
+		else
+		{
+			retrycount++;
+			timespec ts;
+			ts.tv_sec = 1;
+			ts.tv_nsec = 0;
+			nanosleep(&ts,NULL);
+		}
 	}
 	rc = listen(sock, 10);
 	if (rc < 0)

