diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 82a2bc71a0c6e7fb3b386c0cdbf0412c7a474668..46eb38e8e4701516e262807ff8aa15f36063c14a 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.49 2007/06/08 21:21:28 alvherre Exp $
+ *	  $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.50 2007/06/13 21:24:55 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -18,6 +18,7 @@
 
 #include <signal.h>
 #include <sys/types.h>
+#include <sys/time.h>
 #include <time.h>
 #include <unistd.h>
 
@@ -73,6 +74,10 @@ int			autovacuum_vac_cost_limit;
 
 int			Log_autovacuum = -1;
 
+
+/* maximum sleep duration in the launcher, in seconds */
+#define AV_SLEEP_QUANTUM 10
+
 /* Flags to tell if we are in an autovacuum process */
 static bool am_autovacuum_launcher = false;
 static bool am_autovacuum_worker = false;
@@ -197,7 +202,8 @@ NON_EXEC_STATIC void AutoVacWorkerMain(int argc, char *argv[]);
 NON_EXEC_STATIC void AutoVacLauncherMain(int argc, char *argv[]);
 
 static Oid do_start_worker(void);
-static uint64 launcher_determine_sleep(bool canlaunch, bool recursing);
+static void launcher_determine_sleep(bool canlaunch, bool recursing,
+						 struct timeval *nap);
 static void launch_worker(TimestampTz now);
 static List *get_database_list(void);
 static void rebuild_database_list(Oid newdb);
@@ -487,7 +493,7 @@ AutoVacLauncherMain(int argc, char *argv[])
 
 	for (;;)
 	{
-		uint64		micros;
+		struct timeval nap;
 		bool	can_launch;
 		TimestampTz current_time = 0;
 
@@ -498,11 +504,39 @@ AutoVacLauncherMain(int argc, char *argv[])
 		if (!PostmasterIsAlive(true))
 			exit(1);
 
-		micros = launcher_determine_sleep(AutoVacuumShmem->av_freeWorkers !=
-										  INVALID_OFFSET, false);
+		launcher_determine_sleep(AutoVacuumShmem->av_freeWorkers !=
+  								 INVALID_OFFSET, false, &nap);
+
+		/*
+		 * Sleep for a while according to schedule.  We only sleep in
+		 * AV_SLEEP_QUANTUM second intervals, in order to promptly notice
+		 * postmaster death.
+		 */
+		while (nap.tv_sec > 0 || nap.tv_usec > 0)
+		{
+			uint32	sleeptime;
+
+			sleeptime = nap.tv_usec;
+			nap.tv_usec = 0;
 
-		/* Sleep for a while according to schedule */
-		pg_usleep(micros);
+			if (nap.tv_sec > 0)
+			{
+				sleeptime += Min(nap.tv_sec, AV_SLEEP_QUANTUM) * 1000000;
+				nap.tv_sec -= Min(nap.tv_sec, AV_SLEEP_QUANTUM);
+			}
+			
+			pg_usleep(sleeptime);
+
+			/*
+			 * Emergency bailout if postmaster has died.  This is to avoid the
+			 * necessity for manual cleanup of all postmaster children.
+			 */
+			if (!PostmasterIsAlive(true))
+				exit(1);
+
+			if (avlauncher_shutdown_request || got_SIGHUP || got_SIGUSR1)
+				break;
+		}
 
 		/* the normal shutdown case */
 		if (avlauncher_shutdown_request)
@@ -647,16 +681,15 @@ AutoVacLauncherMain(int argc, char *argv[])
 }
 
 /*
- * Determine the time to sleep, in microseconds, based on the database list.
+ * Determine the time to sleep, based on the database list.
  *
  * The "canlaunch" parameter indicates whether we can start a worker right now,
- * for example due to the workers being all busy.
+ * for example due to the workers being all busy.  If this is false, we will
+ * cause a long sleep, which will be interrupted when a worker exits.
  */
-static uint64
-launcher_determine_sleep(bool canlaunch, bool recursing)
+static void
+launcher_determine_sleep(bool canlaunch, bool recursing, struct timeval *nap)
 {
-	long	secs;
-	int		usecs;
 	Dlelem *elem;
 
 	/*
@@ -667,23 +700,28 @@ launcher_determine_sleep(bool canlaunch, bool recursing)
 	 */
 	if (!canlaunch)
 	{
-		secs = autovacuum_naptime;
-		usecs = 0;
+		nap->tv_sec = autovacuum_naptime;
+		nap->tv_usec = 0;
 	}
 	else if ((elem = DLGetTail(DatabaseList)) != NULL)
 	{
 		avl_dbase  *avdb = DLE_VAL(elem);
 		TimestampTz	current_time = GetCurrentTimestamp();
 		TimestampTz	next_wakeup;
+		long	secs;
+		int		usecs;
 
 		next_wakeup = avdb->adl_next_worker;
 		TimestampDifference(current_time, next_wakeup, &secs, &usecs);
+
+		nap->tv_sec = secs;
+		nap->tv_usec = usecs;
 	}
 	else
 	{
 		/* list is empty, sleep for whole autovacuum_naptime seconds  */
-		secs = autovacuum_naptime;
-		usecs = 0;
+		nap->tv_sec = autovacuum_naptime;
+		nap->tv_usec = 0;
 	}
 
 	/*
@@ -696,20 +734,19 @@ launcher_determine_sleep(bool canlaunch, bool recursing)
 	 * We only recurse once.  rebuild_database_list should always return times
 	 * in the future, but it seems best not to trust too much on that.
 	 */
-	if (secs == 0L && usecs == 0 && !recursing)
+	if (nap->tv_sec == 0L && nap->tv_usec == 0 && !recursing)
 	{
 		rebuild_database_list(InvalidOid);
-		return launcher_determine_sleep(canlaunch, true);
+		launcher_determine_sleep(canlaunch, true, nap);
+		return;
 	}
 
 	/* 100ms is the smallest time we'll allow the launcher to sleep */
-	if (secs <= 0L && usecs <= 100000)
+	if (nap->tv_sec <= 0L && nap->tv_usec <= 100000)
 	{
-		secs = 0L;
-		usecs = 100000;	/* 100 ms */
+		nap->tv_sec = 0L;
+		nap->tv_usec = 100000;	/* 100 ms */
 	}
-
-	return secs * 1000000 + usecs;
 }
 
 /*
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 387c4ae1531052dfae4b709bdc15eb95853963fa..e808220b8fb0bf07569f42c6d87a2c456899aed0 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.396 2007/06/08 18:23:52 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.397 2007/06/13 21:24:56 alvherre Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -1645,7 +1645,7 @@ static struct config_int ConfigureNamesInt[] =
 			GUC_UNIT_S
 		},
 		&autovacuum_naptime,
-		60, 1, INT_MAX, NULL, NULL
+		60, 1, INT_MAX / 1000, NULL, NULL
 	},
 	{
 		{"autovacuum_vacuum_threshold", PGC_SIGHUP, AUTOVACUUM,