PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
sinval.c File Reference
#include "postgres.h"
#include "access/xact.h"
#include "miscadmin.h"
#include "storage/latch.h"
#include "storage/sinvaladt.h"
#include "utils/inval.h"
Include dependency graph for sinval.c:

Go to the source code of this file.

Macros

#define MAXINVALMSGS   32
 

Functions

void SendSharedInvalidMessages (const SharedInvalidationMessage *msgs, int n)
 
void ReceiveSharedInvalidMessages (void(*invalFunction)(SharedInvalidationMessage *msg), void(*resetFunction)(void))
 
void HandleCatchupInterrupt (void)
 
void ProcessCatchupInterrupt (void)
 

Variables

uint64 SharedInvalidMessageCounter
 
volatile sig_atomic_t catchupInterruptPending = false
 

Macro Definition Documentation

◆ MAXINVALMSGS

#define MAXINVALMSGS   32

Function Documentation

◆ HandleCatchupInterrupt()

void HandleCatchupInterrupt ( void  )

Definition at line 154 of file sinval.c.

155{
156 /*
157 * Note: this is called by a SIGNAL HANDLER. You must be very wary what
158 * you do here.
159 */
160
162
163 /* make sure the event is processed in due course */
165}
struct Latch * MyLatch
Definition: globals.c:62
void SetLatch(Latch *latch)
Definition: latch.c:632
volatile sig_atomic_t catchupInterruptPending
Definition: sinval.c:39

References catchupInterruptPending, MyLatch, and SetLatch().

Referenced by procsignal_sigusr1_handler().

◆ ProcessCatchupInterrupt()

void ProcessCatchupInterrupt ( void  )

Definition at line 174 of file sinval.c.

175{
177 {
178 /*
179 * What we need to do here is cause ReceiveSharedInvalidMessages() to
180 * run, which will do the necessary work and also reset the
181 * catchupInterruptPending flag. If we are inside a transaction we
182 * can just call AcceptInvalidationMessages() to do this. If we
183 * aren't, we start and immediately end a transaction; the call to
184 * AcceptInvalidationMessages() happens down inside transaction start.
185 *
186 * It is awfully tempting to just call AcceptInvalidationMessages()
187 * without the rest of the xact start/stop overhead, and I think that
188 * would actually work in the normal case; but I am not sure that
189 * things would clean up nicely if we got an error partway through.
190 */
192 {
193 elog(DEBUG4, "ProcessCatchupEvent inside transaction");
195 }
196 else
197 {
198 elog(DEBUG4, "ProcessCatchupEvent outside transaction");
201 }
202 }
203}
#define elog(elevel,...)
Definition: elog.h:225
#define DEBUG4
Definition: elog.h:27
void AcceptInvalidationMessages(void)
Definition: inval.c:863
bool IsTransactionOrTransactionBlock(void)
Definition: xact.c:4981
void StartTransactionCommand(void)
Definition: xact.c:3051
void CommitTransactionCommand(void)
Definition: xact.c:3149

References AcceptInvalidationMessages(), catchupInterruptPending, CommitTransactionCommand(), DEBUG4, elog, IsTransactionOrTransactionBlock(), and StartTransactionCommand().

Referenced by HandleAutoVacLauncherInterrupts(), and ProcessClientReadInterrupt().

◆ ReceiveSharedInvalidMessages()

void ReceiveSharedInvalidMessages ( void(*)(SharedInvalidationMessage *msg)  invalFunction,
void(*)(void)  resetFunction 
)

Definition at line 69 of file sinval.c.

71{
72#define MAXINVALMSGS 32
74
75 /*
76 * We use volatile here to prevent bugs if a compiler doesn't realize that
77 * recursion is a possibility ...
78 */
79 static volatile int nextmsg = 0;
80 static volatile int nummsgs = 0;
81
82 /* Deal with any messages still pending from an outer recursion */
83 while (nextmsg < nummsgs)
84 {
85 SharedInvalidationMessage msg = messages[nextmsg++];
86
88 invalFunction(&msg);
89 }
90
91 do
92 {
93 int getResult;
94
95 nextmsg = nummsgs = 0;
96
97 /* Try to get some more messages */
98 getResult = SIGetDataEntries(messages, MAXINVALMSGS);
99
100 if (getResult < 0)
101 {
102 /* got a reset message */
103 elog(DEBUG4, "cache state reset");
105 resetFunction();
106 break; /* nothing more to do */
107 }
108
109 /* Process them, being wary that a recursive call might eat some */
110 nextmsg = 0;
111 nummsgs = getResult;
112
113 while (nextmsg < nummsgs)
114 {
115 SharedInvalidationMessage msg = messages[nextmsg++];
116
118 invalFunction(&msg);
119 }
120
121 /*
122 * We only need to loop if the last SIGetDataEntries call (which might
123 * have been within a recursive call) returned a full buffer.
124 */
125 } while (nummsgs == MAXINVALMSGS);
126
127 /*
128 * We are now caught up. If we received a catchup signal, reset that
129 * flag, and call SICleanupQueue(). This is not so much because we need
130 * to flush dead messages right now, as that we want to pass on the
131 * catchup signal to the next slowest backend. "Daisy chaining" the
132 * catchup signal this way avoids creating spikes in system load for what
133 * should be just a background maintenance activity.
134 */
136 {
138 elog(DEBUG4, "sinval catchup complete, cleaning queue");
139 SICleanupQueue(false, 0);
140 }
141}
uint64 SharedInvalidMessageCounter
Definition: sinval.c:24
#define MAXINVALMSGS
void SICleanupQueue(bool callerHasWriteLock, int minFree)
Definition: sinvaladt.c:576
int SIGetDataEntries(SharedInvalidationMessage *data, int datasize)
Definition: sinvaladt.c:472

References catchupInterruptPending, DEBUG4, elog, MAXINVALMSGS, SharedInvalidMessageCounter, SICleanupQueue(), and SIGetDataEntries().

Referenced by AcceptInvalidationMessages().

◆ SendSharedInvalidMessages()

void SendSharedInvalidMessages ( const SharedInvalidationMessage msgs,
int  n 
)

Definition at line 47 of file sinval.c.

48{
49 SIInsertDataEntries(msgs, n);
50}
void SIInsertDataEntries(const SharedInvalidationMessage *data, int n)
Definition: sinvaladt.c:369

References SIInsertDataEntries().

Referenced by AtEOXact_Inval(), AtInplace_Inval(), CacheInvalidateRelmap(), CacheInvalidateSmgr(), FinishPreparedTransaction(), and ProcessCommittedInvalidationMessages().

Variable Documentation

◆ catchupInterruptPending

volatile sig_atomic_t catchupInterruptPending = false

◆ SharedInvalidMessageCounter