diff options
-rw-r--r-- | src/backend/storage/ipc/procarray.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index b037e594941..8f110e6ae29 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.19 2006/11/05 22:42:09 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.19.2.1 2009/03/31 05:18:43 heikki Exp $ * *------------------------------------------------------------------------- */ @@ -165,6 +165,7 @@ ProcArrayRemove(PGPROC *proc) 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; @@ -824,6 +825,20 @@ CountActiveBackends(void) { 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) |