mirror of
https://github.com/postgres/postgres.git
synced 2025-11-12 05:01:15 +03:00
Postgres95 1.01 Distribution - Virgin Sources
This commit is contained in:
169
src/backend/storage/ipc/sinval.c
Normal file
169
src/backend/storage/ipc/sinval.c
Normal file
@@ -0,0 +1,169 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* sinval.c--
|
||||
* POSTGRES shared cache invalidation communication code.
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.1.1.1 1996/07/09 06:21:54 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
/* #define INVALIDDEBUG 1 */
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "storage/sinval.h"
|
||||
#include "storage/sinvaladt.h"
|
||||
#include "storage/spin.h"
|
||||
#include "utils/elog.h"
|
||||
|
||||
extern SISeg *shmInvalBuffer;/* the shared buffer segment, set by*/
|
||||
/* SISegmentAttach() */
|
||||
extern BackendId MyBackendId;
|
||||
extern BackendTag MyBackendTag;
|
||||
|
||||
SPINLOCK SInvalLock = (SPINLOCK) NULL;
|
||||
|
||||
/****************************************************************************/
|
||||
/* CreateSharedInvalidationState(key) Create a buffer segment */
|
||||
/* */
|
||||
/* should be called only by the POSTMASTER */
|
||||
/****************************************************************************/
|
||||
void
|
||||
CreateSharedInvalidationState(IPCKey key)
|
||||
{
|
||||
int status;
|
||||
|
||||
/* REMOVED
|
||||
SISyncKill(IPCKeyGetSIBufferMemorySemaphoreKey(key));
|
||||
SISyncInit(IPCKeyGetSIBufferMemorySemaphoreKey(key));
|
||||
*/
|
||||
|
||||
/* SInvalLock gets set in spin.c, during spinlock init */
|
||||
status = SISegmentInit(true, IPCKeyGetSIBufferMemoryBlock(key));
|
||||
|
||||
if (status == -1) {
|
||||
elog(FATAL, "CreateSharedInvalidationState: failed segment init");
|
||||
}
|
||||
}
|
||||
/****************************************************************************/
|
||||
/* AttachSharedInvalidationState(key) Attach a buffer segment */
|
||||
/* */
|
||||
/* should be called only by the POSTMASTER */
|
||||
/****************************************************************************/
|
||||
void
|
||||
AttachSharedInvalidationState(IPCKey key)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (key == PrivateIPCKey) {
|
||||
CreateSharedInvalidationState(key);
|
||||
return;
|
||||
}
|
||||
/* SInvalLock gets set in spin.c, during spinlock init */
|
||||
status = SISegmentInit(false, IPCKeyGetSIBufferMemoryBlock(key));
|
||||
|
||||
if (status == -1) {
|
||||
elog(FATAL, "AttachSharedInvalidationState: failed segment init");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
InitSharedInvalidationState()
|
||||
{
|
||||
SpinAcquire(SInvalLock);
|
||||
if (!SIBackendInit(shmInvalBuffer))
|
||||
{
|
||||
SpinRelease(SInvalLock);
|
||||
elog(FATAL, "Backend cache invalidation initialization failed");
|
||||
}
|
||||
SpinRelease(SInvalLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* RegisterSharedInvalid --
|
||||
* Returns a new local cache invalidation state containing a new entry.
|
||||
*
|
||||
* Note:
|
||||
* Assumes hash index is valid.
|
||||
* Assumes item pointer is valid.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
/* RegisterSharedInvalid(cacheId, hashIndex, pointer) */
|
||||
/* */
|
||||
/* register a message in the buffer */
|
||||
/* should be called by a backend */
|
||||
/****************************************************************************/
|
||||
void
|
||||
RegisterSharedInvalid(int cacheId, /* XXX */
|
||||
Index hashIndex,
|
||||
ItemPointer pointer)
|
||||
{
|
||||
SharedInvalidData newInvalid;
|
||||
|
||||
/*
|
||||
* This code has been hacked to accept two types of messages. This might
|
||||
* be treated more generally in the future.
|
||||
*
|
||||
* (1)
|
||||
* cacheId= system cache id
|
||||
* hashIndex= system cache hash index for a (possibly) cached tuple
|
||||
* pointer= pointer of (possibly) cached tuple
|
||||
*
|
||||
* (2)
|
||||
* cacheId= special non-syscache id
|
||||
* hashIndex= object id contained in (possibly) cached relation descriptor
|
||||
* pointer= null
|
||||
*/
|
||||
|
||||
newInvalid.cacheId = cacheId;
|
||||
newInvalid.hashIndex = hashIndex;
|
||||
|
||||
if (ItemPointerIsValid(pointer)) {
|
||||
ItemPointerCopy(pointer, &newInvalid.pointerData);
|
||||
} else {
|
||||
ItemPointerSetInvalid(&newInvalid.pointerData);
|
||||
}
|
||||
|
||||
SpinAcquire(SInvalLock);
|
||||
if (!SISetDataEntry(shmInvalBuffer, &newInvalid)) {
|
||||
/* buffer full */
|
||||
/* release a message, mark process cache states to be invalid */
|
||||
SISetProcStateInvalid(shmInvalBuffer);
|
||||
|
||||
if (!SIDelDataEntry(shmInvalBuffer)) {
|
||||
/* inconsistent buffer state -- shd never happen */
|
||||
SpinRelease(SInvalLock);
|
||||
elog(FATAL, "RegisterSharedInvalid: inconsistent buffer state");
|
||||
}
|
||||
|
||||
/* write again */
|
||||
(void) SISetDataEntry(shmInvalBuffer, &newInvalid);
|
||||
}
|
||||
SpinRelease(SInvalLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* InvalidateSharedInvalid --
|
||||
* Processes all entries in a shared cache invalidation state.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
/* InvalidateSharedInvalid(invalFunction, resetFunction) */
|
||||
/* */
|
||||
/* invalidate a message in the buffer (read and clean up) */
|
||||
/* should be called by a backend */
|
||||
/****************************************************************************/
|
||||
void
|
||||
InvalidateSharedInvalid(void (*invalFunction)(),
|
||||
void (*resetFunction)())
|
||||
{
|
||||
SpinAcquire(SInvalLock);
|
||||
SIReadEntryData(shmInvalBuffer, MyBackendId,
|
||||
invalFunction, resetFunction);
|
||||
|
||||
SIDelExpiredDataEntries(shmInvalBuffer);
|
||||
SpinRelease(SInvalLock);
|
||||
}
|
||||
Reference in New Issue
Block a user