mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
Restructure backend SIGINT/SIGTERM handling so that 'die' interrupts
are treated more like 'cancel' interrupts: the signal handler sets a flag that is examined at well-defined spots, rather than trying to cope with an interrupt that might happen anywhere. See pghackers discussion of 1/12/01.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.103 2001/01/12 21:53:57 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.104 2001/01/14 05:08:15 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -92,6 +92,7 @@ static Buffer ReadBufferWithBufferLock(Relation relation, BlockNumber blockNum,
|
||||
bool bufferLockHeld);
|
||||
static BufferDesc *BufferAlloc(Relation reln, BlockNumber blockNum,
|
||||
bool *foundPtr, bool bufferLockHeld);
|
||||
static int ReleaseBufferWithBufferLock(Buffer buffer);
|
||||
static int BufferReplace(BufferDesc *bufHdr);
|
||||
void PrintBufferDescs(void);
|
||||
|
||||
@@ -687,10 +688,14 @@ ReleaseAndReadBuffer(Buffer buffer,
|
||||
{
|
||||
bufHdr = &BufferDescriptors[buffer - 1];
|
||||
Assert(PrivateRefCount[buffer - 1] > 0);
|
||||
PrivateRefCount[buffer - 1]--;
|
||||
if (PrivateRefCount[buffer - 1] == 0)
|
||||
if (PrivateRefCount[buffer - 1] > 1)
|
||||
{
|
||||
PrivateRefCount[buffer - 1]--;
|
||||
}
|
||||
else
|
||||
{
|
||||
SpinAcquire(BufMgrLock);
|
||||
PrivateRefCount[buffer - 1] = 0;
|
||||
Assert(bufHdr->refcount > 0);
|
||||
bufHdr->refcount--;
|
||||
if (bufHdr->refcount == 0)
|
||||
@@ -1185,10 +1190,7 @@ recheck:
|
||||
/* Assert checks that buffer will actually get freed! */
|
||||
Assert(PrivateRefCount[i - 1] == 1 &&
|
||||
bufHdr->refcount == 1);
|
||||
/* ReleaseBuffer expects we do not hold the lock at entry */
|
||||
SpinRelease(BufMgrLock);
|
||||
ReleaseBuffer(i);
|
||||
SpinAcquire(BufMgrLock);
|
||||
ReleaseBufferWithBufferLock(i);
|
||||
}
|
||||
/*
|
||||
* And mark the buffer as no longer occupied by this rel.
|
||||
@@ -1270,10 +1272,7 @@ recheck:
|
||||
/* Assert checks that buffer will actually get freed! */
|
||||
Assert(PrivateRefCount[i - 1] == 1 &&
|
||||
bufHdr->refcount == 1);
|
||||
/* ReleaseBuffer expects we do not hold the lock at entry */
|
||||
SpinRelease(BufMgrLock);
|
||||
ReleaseBuffer(i);
|
||||
SpinAcquire(BufMgrLock);
|
||||
ReleaseBufferWithBufferLock(i);
|
||||
}
|
||||
/*
|
||||
* And mark the buffer as no longer occupied by this rel.
|
||||
@@ -1624,10 +1623,14 @@ ReleaseBuffer(Buffer buffer)
|
||||
bufHdr = &BufferDescriptors[buffer - 1];
|
||||
|
||||
Assert(PrivateRefCount[buffer - 1] > 0);
|
||||
PrivateRefCount[buffer - 1]--;
|
||||
if (PrivateRefCount[buffer - 1] == 0)
|
||||
if (PrivateRefCount[buffer - 1] > 1)
|
||||
{
|
||||
PrivateRefCount[buffer - 1]--;
|
||||
}
|
||||
else
|
||||
{
|
||||
SpinAcquire(BufMgrLock);
|
||||
PrivateRefCount[buffer - 1] = 0;
|
||||
Assert(bufHdr->refcount > 0);
|
||||
bufHdr->refcount--;
|
||||
if (bufHdr->refcount == 0)
|
||||
@@ -1641,6 +1644,48 @@ ReleaseBuffer(Buffer buffer)
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* ReleaseBufferWithBufferLock
|
||||
* Same as ReleaseBuffer except we hold the lock
|
||||
*/
|
||||
static int
|
||||
ReleaseBufferWithBufferLock(Buffer buffer)
|
||||
{
|
||||
BufferDesc *bufHdr;
|
||||
|
||||
if (BufferIsLocal(buffer))
|
||||
{
|
||||
Assert(LocalRefCount[-buffer - 1] > 0);
|
||||
LocalRefCount[-buffer - 1]--;
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
if (BAD_BUFFER_ID(buffer))
|
||||
return STATUS_ERROR;
|
||||
|
||||
bufHdr = &BufferDescriptors[buffer - 1];
|
||||
|
||||
Assert(PrivateRefCount[buffer - 1] > 0);
|
||||
if (PrivateRefCount[buffer - 1] > 1)
|
||||
{
|
||||
PrivateRefCount[buffer - 1]--;
|
||||
}
|
||||
else
|
||||
{
|
||||
PrivateRefCount[buffer - 1] = 0;
|
||||
Assert(bufHdr->refcount > 0);
|
||||
bufHdr->refcount--;
|
||||
if (bufHdr->refcount == 0)
|
||||
{
|
||||
AddBufferToFreelist(bufHdr);
|
||||
bufHdr->flags |= BM_FREE;
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifdef NOT_USED
|
||||
void
|
||||
IncrBufferRefCount_Debug(char *file, int line, Buffer buffer)
|
||||
@@ -2217,9 +2262,9 @@ MarkBufferForCleanup(Buffer buffer, void (*CleanupFunc)(Buffer))
|
||||
SpinRelease(BufMgrLock);
|
||||
|
||||
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
|
||||
PrivateRefCount[buffer - 1]--;
|
||||
|
||||
SpinAcquire(BufMgrLock);
|
||||
PrivateRefCount[buffer - 1] = 0;
|
||||
Assert(bufHdr->refcount > 0);
|
||||
bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
|
||||
bufHdr->CleanupFunc = CleanupFunc;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/Attic/s_lock.c,v 1.28 2000/12/29 21:31:20 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/Attic/s_lock.c,v 1.29 2001/01/14 05:08:15 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "miscadmin.h"
|
||||
#include "storage/s_lock.h"
|
||||
|
||||
|
||||
@@ -101,10 +102,16 @@ s_lock(volatile slock_t *lock, const char *file, const int line)
|
||||
/*
|
||||
* If you are thinking of changing this code, be careful. This same
|
||||
* loop logic is used in other places that call TAS() directly.
|
||||
*
|
||||
* While waiting for a lock, we check for cancel/die interrupts (which
|
||||
* is a no-op if we are inside a critical section). The interrupt check
|
||||
* can be omitted in places that know they are inside a critical section.
|
||||
* Note that an interrupt must NOT be accepted after acquiring the lock.
|
||||
*/
|
||||
while (TAS(lock))
|
||||
{
|
||||
s_lock_sleep(spins++, 0, lock, file, line);
|
||||
CHECK_FOR_INTERRUPTS();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user