aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/storage/ipc/procarray.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 575b138c435..a9ae969f31e 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -23,7 +23,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.40 2008/01/09 21:52:36 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.40.2.1 2009/03/31 05:18:39 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -198,6 +198,7 @@ ProcArrayRemove(PGPROC *proc, TransactionId latestXid)
if (arrayP->procs[index] == proc)
{
arrayP->procs[index] = arrayP->procs[arrayP->numProcs - 1];
+ arrayP->procs[arrayP->numProcs - 1] = NULL; /* for debugging */
arrayP->numProcs--;
LWLockRelease(ProcArrayLock);
return;
@@ -1089,6 +1090,20 @@ CountActiveBackends(void)
{
volatile PGPROC *proc = arrayP->procs[index];
+ /*
+ * Since we're not holding a lock, need to check that the pointer is
+ * valid. Someone holding the lock could have incremented numProcs
+ * already, but not yet inserted a valid pointer to the array.
+ *
+ * If someone just decremented numProcs, 'proc' could also point to a
+ * PGPROC entry that's no longer in the array. It still points to a
+ * PGPROC struct, though, because freed PGPPROC entries just go to
+ * the free list and are recycled. Its contents are nonsense in that
+ * case, but that's acceptable for this function.
+ */
+ if (proc != NULL)
+ continue;
+
if (proc == MyProc)
continue; /* do not count myself */
if (proc->pid == 0)