summaryrefslogtreecommitdiff
path: root/src/backend/storage/ipc/sinval.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>1999-09-04 18:36:45 +0000
committerTom Lane <tgl@sss.pgh.pa.us>1999-09-04 18:36:45 +0000
commit8add6d71cff28d087872215b02c7a0b84ba786c4 (patch)
tree725119fddb5021fb515e4c8a46dbc18b08f9ed43 /src/backend/storage/ipc/sinval.c
parentae01c7f5bb4f40386e64138ae33b12f862f13796 (diff)
Modify sinval so that InvalidateSharedInvalid() does not hold
the SInval spinlock while it is calling the passed invalFunction or resetFunction. This is necessary to avoid deadlock with lmgr change; InvalidateSharedInvalid can be called recursively now. It should be a good performance improvement anyway --- holding a spinlock for more than a very short interval is a no-no.
Diffstat (limited to 'src/backend/storage/ipc/sinval.c')
-rw-r--r--src/backend/storage/ipc/sinval.c57
1 files changed, 42 insertions, 15 deletions
diff --git a/src/backend/storage/ipc/sinval.c b/src/backend/storage/ipc/sinval.c
index 21585cc2406..e993cef74aa 100644
--- a/src/backend/storage/ipc/sinval.c
+++ b/src/backend/storage/ipc/sinval.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.16 1999/07/15 22:39:49 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.17 1999/09/04 18:36:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,9 +21,9 @@
#include "storage/sinval.h"
#include "storage/sinvaladt.h"
-extern SISeg *shmInvalBuffer; /* the shared buffer segment, set by */
-
- /* SISegmentAttach() */
+extern SISeg *shmInvalBuffer; /* the shared buffer segment, set by
+ * SISegmentAttach()
+ */
extern BackendId MyBackendId;
extern BackendTag MyBackendTag;
@@ -127,21 +127,20 @@ RegisterSharedInvalid(int cacheId, /* XXX */
ItemPointerSetInvalid(&newInvalid.pointerData);
SpinAcquire(SInvalLock);
- if (!SISetDataEntry(shmInvalBuffer, &newInvalid))
+ while (!SISetDataEntry(shmInvalBuffer, &newInvalid))
{
/* buffer full */
/* release a message, mark process cache states to be invalid */
SISetProcStateInvalid(shmInvalBuffer);
- if (!SIDelDataEntry(shmInvalBuffer))
+ if (!SIDelDataEntries(shmInvalBuffer, 1))
{
/* inconsistent buffer state -- shd never happen */
SpinRelease(SInvalLock);
elog(FATAL, "RegisterSharedInvalid: inconsistent buffer state");
}
- /* write again */
- SISetDataEntry(shmInvalBuffer, &newInvalid);
+ /* loop around to try write again */
}
SpinRelease(SInvalLock);
}
@@ -157,13 +156,41 @@ RegisterSharedInvalid(int cacheId, /* XXX */
/* should be called by a backend */
/****************************************************************************/
void
- InvalidateSharedInvalid(void (*invalFunction) (),
- void (*resetFunction) ())
+InvalidateSharedInvalid(void (*invalFunction) (),
+ void (*resetFunction) ())
{
- SpinAcquire(SInvalLock);
- SIReadEntryData(shmInvalBuffer, MyBackendId,
- invalFunction, resetFunction);
+ SharedInvalidData data;
+ int getResult;
+ bool gotMessage = false;
- SIDelExpiredDataEntries(shmInvalBuffer);
- SpinRelease(SInvalLock);
+ for (;;)
+ {
+ SpinAcquire(SInvalLock);
+ getResult = SIGetDataEntry(shmInvalBuffer, MyBackendId, &data);
+ SpinRelease(SInvalLock);
+ if (getResult == 0)
+ break; /* nothing more to do */
+ if (getResult < 0)
+ {
+ /* got a reset message */
+ elog(NOTICE, "InvalidateSharedInvalid: cache state reset");
+ resetFunction();
+ }
+ else
+ {
+ /* got a normal data message */
+ invalFunction(data.cacheId,
+ data.hashIndex,
+ &data.pointerData);
+ }
+ gotMessage = true;
+ }
+
+ /* If we got any messages, try to release dead messages */
+ if (gotMessage)
+ {
+ SpinAcquire(SInvalLock);
+ SIDelExpiredDataEntries(shmInvalBuffer);
+ SpinRelease(SInvalLock);
+ }
}