Index: src/backend/access/transam/twophase.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/access/transam/twophase.c,v
retrieving revision 1.26
diff -c -p -r1.26 twophase.c
*** src/backend/access/transam/twophase.c	5 Jan 2007 22:19:23 -0000	1.26
--- src/backend/access/transam/twophase.c	15 Jan 2007 19:11:15 -0000
*************** MarkAsPreparing(TransactionId xid, const
*** 280,285 ****
--- 280,286 ----
  	gxact->proc.databaseId = databaseid;
  	gxact->proc.roleId = owner;
  	gxact->proc.inVacuum = false;
+ 	gxact->proc.isAutovacuum = false;
  	gxact->proc.lwWaiting = false;
  	gxact->proc.lwExclusive = false;
  	gxact->proc.lwWaitLink = NULL;
Index: src/backend/commands/dbcommands.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/commands/dbcommands.c,v
retrieving revision 1.188
diff -c -p -r1.188 dbcommands.c
*** src/backend/commands/dbcommands.c	5 Jan 2007 22:19:25 -0000	1.188
--- src/backend/commands/dbcommands.c	15 Jan 2007 22:00:56 -0000
*************** createdb(const CreatedbStmt *stmt)
*** 250,260 ****
  	 * (exception is to allow CREATE DB while connected to template1).
  	 * Otherwise we might copy inconsistent data.
  	 */
! 	if (DatabaseHasActiveBackends(src_dboid, true))
  		ereport(ERROR,
  				(errcode(ERRCODE_OBJECT_IN_USE),
! 			errmsg("source database \"%s\" is being accessed by other users",
! 				   dbtemplate)));
  
  	/* If encoding is defaulted, use source's encoding */
  	if (encoding < 0)
--- 250,260 ----
  	 * (exception is to allow CREATE DB while connected to template1).
  	 * Otherwise we might copy inconsistent data.
  	 */
! 	if (DatabaseCancelAutovacuumActivity(src_dboid, true))
  		ereport(ERROR,
  				(errcode(ERRCODE_OBJECT_IN_USE),
! 				 errmsg("source database \"%s\" is being accessed by other users",
! 						dbtemplate)));
  
  	/* If encoding is defaulted, use source's encoding */
  	if (encoding < 0)
*************** dropdb(const char *dbname, bool missing_
*** 602,608 ****
  	 * Check for active backends in the target database.  (Because we hold the
  	 * database lock, no new ones can start after this.)
  	 */
! 	if (DatabaseHasActiveBackends(db_id, false))
  		ereport(ERROR,
  				(errcode(ERRCODE_OBJECT_IN_USE),
  				 errmsg("database \"%s\" is being accessed by other users",
--- 602,608 ----
  	 * Check for active backends in the target database.  (Because we hold the
  	 * database lock, no new ones can start after this.)
  	 */
! 	if (DatabaseCancelAutovacuumActivity(db_id, false))
  		ereport(ERROR,
  				(errcode(ERRCODE_OBJECT_IN_USE),
  				 errmsg("database \"%s\" is being accessed by other users",
*************** RenameDatabase(const char *oldname, cons
*** 706,712 ****
  	 * Make sure the database does not have active sessions.  This is the same
  	 * concern as above, but applied to other sessions.
  	 */
! 	if (DatabaseHasActiveBackends(db_id, false))
  		ereport(ERROR,
  				(errcode(ERRCODE_OBJECT_IN_USE),
  				 errmsg("database \"%s\" is being accessed by other users",
--- 706,712 ----
  	 * Make sure the database does not have active sessions.  This is the same
  	 * concern as above, but applied to other sessions.
  	 */
! 	if (DatabaseCancelAutovacuumActivity(db_id, false))
  		ereport(ERROR,
  				(errcode(ERRCODE_OBJECT_IN_USE),
  				 errmsg("database \"%s\" is being accessed by other users",
Index: src/backend/postmaster/autovacuum.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/postmaster/autovacuum.c,v
retrieving revision 1.30
diff -c -p -r1.30 autovacuum.c
*** src/backend/postmaster/autovacuum.c	5 Jan 2007 22:19:36 -0000	1.30
--- src/backend/postmaster/autovacuum.c	15 Jan 2007 21:48:08 -0000
*************** autovac_forkexec(void)
*** 216,221 ****
--- 216,230 ----
  
  	return postmaster_forkexec(ac, av);
  }
+ 
+ /*
+  * We need this set from the outside, before InitProcess is called
+  */
+ void
+ AutovacuumIAm(void)
+ {
+ 	am_autovacuum = true;
+ }
  #endif   /* EXEC_BACKEND */
  
  /*
*************** AutoVacMain(int argc, char *argv[])
*** 307,313 ****
  		EmitErrorReport();
  
  		/*
! 		 * We can now go away.	Note that because we'll call InitProcess, a
  		 * callback will be registered to do ProcKill, which will clean up
  		 * necessary state.
  		 */
--- 316,322 ----
  		EmitErrorReport();
  
  		/*
! 		 * We can now go away.	Note that because we called InitProcess, a
  		 * callback will be registered to do ProcKill, which will clean up
  		 * necessary state.
  		 */
Index: src/backend/postmaster/postmaster.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/postmaster/postmaster.c,v
retrieving revision 1.507
diff -c -p -r1.507 postmaster.c
*** src/backend/postmaster/postmaster.c	5 Jan 2007 22:19:36 -0000	1.507
--- src/backend/postmaster/postmaster.c	15 Jan 2007 21:48:20 -0000
*************** SubPostmasterMain(int argc, char *argv[]
*** 3298,3303 ****
--- 3298,3307 ----
  		strcmp(argv[1], "--forkboot") == 0)
  		PGSharedMemoryReAttach();
  
+ 	/* autovacuum needs this set before calling InitProcess */
+ 	if (strcmp(argv[1], "--forkautovac") == 0)
+ 		AutovacuumIAm();
+ 
  	/*
  	 * Start our win32 signal implementation. This has to be done after we
  	 * read the backend variables, because we need to pick up the signal pipe
Index: src/backend/storage/ipc/procarray.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/storage/ipc/procarray.c,v
retrieving revision 1.20
diff -c -p -r1.20 procarray.c
*** src/backend/storage/ipc/procarray.c	5 Jan 2007 22:19:38 -0000	1.20
--- src/backend/storage/ipc/procarray.c	15 Jan 2007 22:08:48 -0000
***************
*** 29,34 ****
--- 29,36 ----
   */
  #include "postgres.h"
  
+ #include <signal.h>
+ 
  #include "access/subtrans.h"
  #include "access/transam.h"
  #include "access/xact.h"
*************** GetSnapshotData(Snapshot snapshot, bool 
*** 678,684 ****
  }
  
  /*
!  * DatabaseHasActiveBackends -- are there any backends running in the given DB
   *
   * If 'ignoreMyself' is TRUE, ignore this particular backend while checking
   * for backends in the target database.
--- 680,688 ----
  }
  
  /*
!  * DatabaseCancelAutovacuumActivity -- are there any backends running in the
!  * given DB, apart from autovacuum?  If an autovacuum process is running on the
!  * database, kill it and restart the counting.
   *
   * If 'ignoreMyself' is TRUE, ignore this particular backend while checking
   * for backends in the target database.
*************** GetSnapshotData(Snapshot snapshot, bool 
*** 691,701 ****
   * backend startup.
   */
  bool
! DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself)
  {
- 	bool		result = false;
  	ProcArrayStruct *arrayP = procArray;
  	int			index;
  
  	LWLockAcquire(ProcArrayLock, LW_SHARED);
  
--- 695,710 ----
   * backend startup.
   */
  bool
! DatabaseCancelAutovacuumActivity(Oid databaseId, bool ignoreMyself)
  {
  	ProcArrayStruct *arrayP = procArray;
  	int			index;
+ 	int			num;
+ 
+ restart:
+ 	num = 0;
+ 
+ 	CHECK_FOR_INTERRUPTS();
  
  	LWLockAcquire(ProcArrayLock, LW_SHARED);
  
*************** DatabaseHasActiveBackends(Oid databaseId
*** 708,721 ****
  			if (ignoreMyself && proc == MyProc)
  				continue;
  
! 			result = true;
! 			break;
  		}
  	}
  
  	LWLockRelease(ProcArrayLock);
  
! 	return result;
  }
  
  /*
--- 717,738 ----
  			if (ignoreMyself && proc == MyProc)
  				continue;
  
! 			num++;
! 
! 			if (proc->isAutovacuum)
! 			{
! 				/* an autovacuum -- kill it and restart */
! 				LWLockRelease(ProcArrayLock);
! 				kill(proc->pid, SIGINT);
! 				pg_usleep(100 * 1000);		/* 100ms */
! 				goto restart;
! 			}
  		}
  	}
  
  	LWLockRelease(ProcArrayLock);
  
! 	return (num != 0);
  }
  
  /*
Index: src/backend/storage/lmgr/proc.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/storage/lmgr/proc.c,v
retrieving revision 1.182
diff -c -p -r1.182 proc.c
*** src/backend/storage/lmgr/proc.c	5 Jan 2007 22:19:38 -0000	1.182
--- src/backend/storage/lmgr/proc.c	15 Jan 2007 22:03:04 -0000
***************
*** 38,43 ****
--- 38,44 ----
  #include "access/transam.h"
  #include "access/xact.h"
  #include "miscadmin.h"
+ #include "postmaster/autovacuum.h"
  #include "storage/ipc.h"
  #include "storage/proc.h"
  #include "storage/procarray.h"
*************** InitProcess(void)
*** 258,263 ****
--- 259,265 ----
  	MyProc->databaseId = InvalidOid;
  	MyProc->roleId = InvalidOid;
  	MyProc->inVacuum = false;
+ 	MyProc->isAutovacuum = IsAutoVacuumProcess();
  	MyProc->lwWaiting = false;
  	MyProc->lwExclusive = false;
  	MyProc->lwWaitLink = NULL;
*************** InitDummyProcess(void)
*** 390,395 ****
--- 392,398 ----
  	MyProc->databaseId = InvalidOid;
  	MyProc->roleId = InvalidOid;
  	MyProc->inVacuum = false;
+ 	MyProc->isAutovacuum = false;
  	MyProc->lwWaiting = false;
  	MyProc->lwExclusive = false;
  	MyProc->lwWaitLink = NULL;
Index: src/include/postmaster/autovacuum.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/include/postmaster/autovacuum.h,v
retrieving revision 1.6
diff -c -p -r1.6 autovacuum.h
*** src/include/postmaster/autovacuum.h	5 Jan 2007 22:19:57 -0000	1.6
--- src/include/postmaster/autovacuum.h	15 Jan 2007 21:47:00 -0000
*************** extern void autovac_stopped(void);
*** 36,41 ****
--- 36,42 ----
  
  #ifdef EXEC_BACKEND
  extern void AutoVacMain(int argc, char *argv[]);
+ extern void AutovacuumIAm(void);
  #endif
  
  #endif   /* AUTOVACUUM_H */
Index: src/include/storage/proc.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/include/storage/proc.h,v
retrieving revision 1.92
diff -c -p -r1.92 proc.h
*** src/include/storage/proc.h	5 Jan 2007 22:19:58 -0000	1.92
--- src/include/storage/proc.h	15 Jan 2007 20:49:10 -0000
*************** struct PGPROC
*** 75,80 ****
--- 75,81 ----
  	Oid			roleId;			/* OID of role using this backend */
  
  	bool		inVacuum;		/* true if current xact is a LAZY VACUUM */
+ 	bool		isAutovacuum;	/* true if it's autovacuum */
  
  	/* Info about LWLock the process is currently waiting for, if any. */
  	bool		lwWaiting;		/* true if waiting for an LW lock */
Index: src/include/storage/procarray.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/include/storage/procarray.h,v
retrieving revision 1.11
diff -c -p -r1.11 procarray.h
*** src/include/storage/procarray.h	5 Jan 2007 22:19:58 -0000	1.11
--- src/include/storage/procarray.h	15 Jan 2007 22:00:08 -0000
*************** extern TransactionId GetOldestXmin(bool 
*** 29,35 ****
  extern PGPROC *BackendPidGetProc(int pid);
  extern int	BackendXidGetPid(TransactionId xid);
  extern bool IsBackendPid(int pid);
! extern bool DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself);
  
  extern int	CountActiveBackends(void);
  extern int	CountDBBackends(Oid databaseid);
--- 29,35 ----
  extern PGPROC *BackendPidGetProc(int pid);
  extern int	BackendXidGetPid(TransactionId xid);
  extern bool IsBackendPid(int pid);
! extern bool DatabaseCancelAutovacuumActivity(Oid databaseId, bool ignoreMyself);
  
  extern int	CountActiveBackends(void);
  extern int	CountDBBackends(Oid databaseid);
