From 8a6fab412e35d8495201a13d8258f26b730306f5 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Wed, 25 Sep 2002 20:31:40 +0000
Subject: [PATCH] Remove ShutdownBufferPoolAccess exit callback, and do the
 work in ProcKill instead, where we still have a PGPROC with which to wait on
 LWLocks.  This fixes 'can't wait without a PROC structure' failures
 occasionally seen during backend shutdown (I'm surprised they weren't more
 frequent, actually).  Add an Assert() to LWLockAcquire to help catch any
 similar mistakes in future.  Fix failure to update MyProcPid for standalone
 backends and pgstat processes.

---
 src/backend/bootstrap/bootstrap.c     |  7 ++++---
 src/backend/postmaster/pgstat.c       |  6 +++++-
 src/backend/storage/buffer/buf_init.c | 29 +++++----------------------
 src/backend/storage/lmgr/lwlock.c     |  9 ++++++++-
 src/backend/storage/lmgr/proc.c       | 15 +++++++++++---
 src/backend/tcop/postgres.c           | 11 ++++++++--
 6 files changed, 43 insertions(+), 34 deletions(-)

diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index b22631700b4..4df563b4285 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.142 2002/09/22 19:42:50 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.143 2002/09/25 20:31:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -369,6 +369,9 @@ BootstrapMain(int argc, char *argv[])
 
 	BaseInit();
 
+	if (IsUnderPostmaster)
+		InitDummyProcess();		/* needed to get LWLocks */
+
 	/*
 	 * XLOG operations
 	 */
@@ -386,8 +389,6 @@ BootstrapMain(int argc, char *argv[])
 			break;
 
 		case BS_XLOG_CHECKPOINT:
-			if (IsUnderPostmaster)
-				InitDummyProcess();		/* needed to get LWLocks */
 			CreateDummyCaches();
 			CreateCheckPoint(false);
 			SetSavedRedoRecPtr();		/* pass redo ptr back to
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 50580a8ee10..9c7795cd26e 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -16,7 +16,7 @@
  *
  *	Copyright (c) 2001, PostgreSQL Global Development Group
  *
- *	$Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.28 2002/09/05 18:26:18 petere Exp $
+ *	$Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.29 2002/09/25 20:31:40 tgl Exp $
  * ----------
  */
 #include "postgres.h"
@@ -314,6 +314,8 @@ pgstat_start(void)
 
 	IsUnderPostmaster = true;	/* we are a postmaster subprocess now */
 
+	MyProcPid = getpid();		/* reset MyProcPid */
+
 	/* Lose the postmaster's on-exit routines */
 	on_exit_reset();
 
@@ -1190,6 +1192,8 @@ pgstat_main(void)
 	 */
 	pqsignal(SIGCHLD, SIG_DFL);
 
+	MyProcPid = getpid();		/* reset MyProcPid */
+
 	/*
 	 * Identify myself via ps
 	 */
diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c
index dd6478c195d..3d25381c14d 100644
--- a/src/backend/storage/buffer/buf_init.c
+++ b/src/backend/storage/buffer/buf_init.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.52 2002/09/04 20:31:25 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.53 2002/09/25 20:31:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -35,8 +35,6 @@
 #include "utils/memutils.h"
 
 
-static void ShutdownBufferPoolAccess(void);
-
 /*
  *	if BMTRACE is defined, we trace the last 200 buffer allocations and
  *	deallocations in a circular buffer in shared memory.
@@ -219,6 +217,10 @@ InitBufferPool(void)
  * This is called during backend startup (whether standalone or under the
  * postmaster).  It sets up for this backend's access to the already-existing
  * buffer pool.
+ *
+ * NB: this is called before InitProcess(), so we do not have a PGPROC and
+ * cannot do LWLockAcquire; hence we can't actually access the bufmgr's
+ * shared memory yet.  We are only initializing local data here.
  */
 void
 InitBufferPoolAccess(void)
@@ -238,27 +240,6 @@ InitBufferPoolAccess(void)
 	 */
 	for (i = 0; i < NBuffers; i++)
 		BufferBlockPointers[i] = (Block) MAKE_PTR(BufferDescriptors[i].data);
-
-	/*
-	 * Now that buffer access is initialized, set up a callback to shut it
-	 * down again at backend exit.
-	 */
-	on_shmem_exit(ShutdownBufferPoolAccess, 0);
-}
-
-/*
- * Shut down buffer manager at backend exit.
- *
- * This is needed mainly to ensure that we don't leave any buffer reference
- * counts set during an error exit.
- */
-static void
-ShutdownBufferPoolAccess(void)
-{
-	/* Release any buffer context locks we are holding */
-	UnlockBuffers();
-	/* Release any buffer reference counts we are holding */
-	AtEOXact_Buffers(false);
 }
 
 /* -----------------------------------------------------
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index e2559be0e6f..8eaf7521830 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lwlock.c,v 1.13 2002/09/04 20:31:26 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lwlock.c,v 1.14 2002/09/25 20:31:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -203,6 +203,13 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode)
 
 	PRINT_LWDEBUG("LWLockAcquire", lockid, lock);
 
+	/*
+	 * We can't wait if we haven't got a PGPROC.  This should only occur
+	 * during bootstrap or shared memory initialization.  Put an Assert
+	 * here to catch unsafe coding practices.
+	 */
+	Assert(!(proc == NULL && IsUnderPostmaster));
+
 	/*
 	 * Lock out cancel/die interrupts until we exit the code section
 	 * protected by the LWLock.  This ensures that interrupts will not
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 5dceb721abd..04f57707d19 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.125 2002/09/04 20:31:26 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.126 2002/09/25 20:31:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -391,8 +391,15 @@ ProcKill(void)
 	/* Release any LW locks I am holding */
 	LWLockReleaseAll();
 
-	/* Abort any buffer I/O in progress */
+	/*
+	 * Make real sure we release any buffer locks and pins we might be
+	 * holding, too.  It is pretty ugly to do this here and not in a
+	 * shutdown callback registered by the bufmgr ... but we must do this
+	 * *after* LWLockReleaseAll and *before* zapping MyProc.
+	 */
 	AbortBufferIO();
+	UnlockBuffers();
+	AtEOXact_Buffers(false);
 
 	/* Get off any wait queue I might be on */
 	LockWaitCancel();
@@ -430,8 +437,10 @@ DummyProcKill(void)
 	/* Release any LW locks I am holding */
 	LWLockReleaseAll();
 
-	/* Abort any buffer I/O in progress */
+	/* Release buffer locks and pins, too */
 	AbortBufferIO();
+	UnlockBuffers();
+	AtEOXact_Buffers(false);
 
 	/* I can't be on regular lock queues, so needn't check */
 
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 0b713f25a48..6b49bdba6c5 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.293 2002/09/20 03:45:08 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.294 2002/09/25 20:31:40 tgl Exp $
  *
  * NOTES
  *	  this is the "main" module of the postgres backend and
@@ -1163,6 +1163,13 @@ PostgresMain(int argc, char *argv[], const char *username)
 		}
 	}
 
+	/*
+	 * initialize globals (already done if under postmaster, but not if
+	 * standalone; cheap enough to do over)
+	 */
+
+	MyProcPid = getpid();
+
 	/*
 	 * Fire up essential subsystems: error and memory management
 	 *
@@ -1691,7 +1698,7 @@ PostgresMain(int argc, char *argv[], const char *username)
 	if (!IsUnderPostmaster)
 	{
 		puts("\nPOSTGRES backend interactive interface ");
-		puts("$Revision: 1.293 $ $Date: 2002/09/20 03:45:08 $\n");
+		puts("$Revision: 1.294 $ $Date: 2002/09/25 20:31:40 $\n");
 	}
 
 	/*
-- 
GitLab