Skip to content

Commit 56817ad

Browse files
Add patches to 11 version
1 parent 11b173f commit 56817ad

File tree

2 files changed

+506
-0
lines changed

2 files changed

+506
-0
lines changed

patches/custom_signals_11.0.patch

+258
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
2+
index b0dd7d1b37..7415b7f7f5 100644
3+
--- a/src/backend/storage/ipc/procsignal.c
4+
+++ b/src/backend/storage/ipc/procsignal.c
5+
@@ -27,6 +27,7 @@
6+
#include "storage/shmem.h"
7+
#include "storage/sinval.h"
8+
#include "tcop/tcopprot.h"
9+
+#include "utils/memutils.h"
10+
11+
12+
/*
13+
@@ -60,12 +61,17 @@ typedef struct
14+
*/
15+
#define NumProcSignalSlots (MaxBackends + NUM_AUXPROCTYPES)
16+
17+
+static bool CustomSignalPendings[NUM_CUSTOM_PROCSIGNALS];
18+
+static ProcSignalHandler_type CustomHandlers[NUM_CUSTOM_PROCSIGNALS];
19+
+
20+
static ProcSignalSlot *ProcSignalSlots = NULL;
21+
static volatile ProcSignalSlot *MyProcSignalSlot = NULL;
22+
23+
static bool CheckProcSignal(ProcSignalReason reason);
24+
static void CleanupProcSignalState(int status, Datum arg);
25+
26+
+static void CustomSignalInterrupt(ProcSignalReason reason);
27+
+
28+
/*
29+
* ProcSignalShmemSize
30+
* Compute space needed for procsignal's shared memory
31+
@@ -165,6 +171,57 @@ CleanupProcSignalState(int status, Datum arg)
32+
slot->pss_pid = 0;
33+
}
34+
35+
+/*
36+
+ * RegisterCustomProcSignalHandler
37+
+ * Assign specific handler for custom process signal with new ProcSignalReason key.
38+
+ * Return INVALID_PROCSIGNAL if all custom signals have been assigned.
39+
+ */
40+
+ProcSignalReason
41+
+RegisterCustomProcSignalHandler(ProcSignalHandler_type handler)
42+
+{
43+
+ ProcSignalReason reason;
44+
+
45+
+ /* iterate through custom signal keys to find free spot */
46+
+ for (reason = PROCSIG_CUSTOM_1; reason <= PROCSIG_CUSTOM_N; reason++)
47+
+ if (!CustomHandlers[reason - PROCSIG_CUSTOM_1])
48+
+ {
49+
+ CustomHandlers[reason - PROCSIG_CUSTOM_1] = handler;
50+
+ return reason;
51+
+ }
52+
+ return INVALID_PROCSIGNAL;
53+
+}
54+
+
55+
+/*
56+
+ * AssignCustomProcSignalHandler
57+
+ * Assign handler of custom process signal with specific ProcSignalReason key.
58+
+ * Return old ProcSignal handler.
59+
+ * Assume incoming reason is one of custom ProcSignals.
60+
+ */
61+
+ProcSignalHandler_type
62+
+AssignCustomProcSignalHandler(ProcSignalReason reason, ProcSignalHandler_type handler)
63+
+{
64+
+ ProcSignalHandler_type old;
65+
+
66+
+ AssertArg(reason >= PROCSIG_CUSTOM_1 && reason <= PROCSIG_CUSTOM_N);
67+
+
68+
+ old = CustomHandlers[reason - PROCSIG_CUSTOM_1];
69+
+ CustomHandlers[reason - PROCSIG_CUSTOM_1] = handler;
70+
+ return old;
71+
+}
72+
+
73+
+/*
74+
+ * GetCustomProcSignalHandler
75+
+ * Get handler of custom process signal.
76+
+ * Assume incoming reason is one of custom ProcSignals.
77+
+ */
78+
+ProcSignalHandler_type
79+
+GetCustomProcSignalHandler(ProcSignalReason reason)
80+
+{
81+
+ AssertArg(reason >= PROCSIG_CUSTOM_1 && reason <= PROCSIG_CUSTOM_N);
82+
+
83+
+ return CustomHandlers[reason - PROCSIG_CUSTOM_1];
84+
+}
85+
+
86+
/*
87+
* SendProcSignal
88+
* Send a signal to a Postgres process
89+
@@ -260,7 +317,8 @@ CheckProcSignal(ProcSignalReason reason)
90+
void
91+
procsignal_sigusr1_handler(SIGNAL_ARGS)
92+
{
93+
- int save_errno = errno;
94+
+ int save_errno = errno;
95+
+ ProcSignalReason reason;
96+
97+
if (CheckProcSignal(PROCSIG_CATCHUP_INTERRUPT))
98+
HandleCatchupInterrupt();
99+
@@ -292,9 +350,87 @@ procsignal_sigusr1_handler(SIGNAL_ARGS)
100+
if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN))
101+
RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN);
102+
103+
+ for (reason = PROCSIG_CUSTOM_1; reason <= PROCSIG_CUSTOM_N; reason++)
104+
+ if (CheckProcSignal(reason))
105+
+ CustomSignalInterrupt(reason);
106+
+
107+
SetLatch(MyLatch);
108+
109+
latch_sigusr1_handler();
110+
111+
errno = save_errno;
112+
}
113+
+
114+
+/*
115+
+ * Handle receipt of an interrupt indicating a custom process signal.
116+
+ */
117+
+static void
118+
+CustomSignalInterrupt(ProcSignalReason reason)
119+
+{
120+
+ int save_errno = errno;
121+
+
122+
+ AssertArg(reason >= PROCSIG_CUSTOM_1 && reason <= PROCSIG_CUSTOM_N);
123+
+
124+
+ /* set interrupt flags */
125+
+ InterruptPending = true;
126+
+ CustomSignalPendings[reason - PROCSIG_CUSTOM_1] = true;
127+
+
128+
+ /* make sure the event is processed in due course */
129+
+ SetLatch(MyLatch);
130+
+
131+
+ errno = save_errno;
132+
+}
133+
+
134+
+/*
135+
+ * CheckAndHandleCustomSignals
136+
+ * Check custom signal flags and call handler assigned to that signal if it is not NULL.
137+
+ * This function is called within CHECK_FOR_INTERRUPTS if interrupt have been occurred.
138+
+ */
139+
+void
140+
+CheckAndHandleCustomSignals(void)
141+
+{
142+
+ int i;
143+
+ MemoryContext oldcontext;
144+
+
145+
+ static MemoryContext hcs_context = NULL;
146+
+
147+
+ /*
148+
+ * This is invoked from ProcessInterrupts(), and since some of the
149+
+ * functions it calls contain CHECK_FOR_INTERRUPTS(), there is a potential
150+
+ * for recursive calls if more signals are received while this runs, so
151+
+ * let's block interrupts until done.
152+
+ */
153+
+ HOLD_INTERRUPTS();
154+
+
155+
+ /*
156+
+ * Moreover, CurrentMemoryContext might be pointing almost anywhere. We
157+
+ * don't want to risk leaking data into long-lived contexts, so let's do
158+
+ * our work here in a private context that we can reset on each use.
159+
+ */
160+
+ if (hcs_context == NULL) /* first time through? */
161+
+ hcs_context = AllocSetContextCreate(TopMemoryContext,
162+
+ "HandleCustomSignals",
163+
+ ALLOCSET_DEFAULT_SIZES);
164+
+ else
165+
+ MemoryContextReset(hcs_context);
166+
+
167+
+ oldcontext = MemoryContextSwitchTo(hcs_context);
168+
+
169+
+ for (i = 0; i < NUM_CUSTOM_PROCSIGNALS; i++)
170+
+ if (CustomSignalPendings[i])
171+
+ {
172+
+ ProcSignalHandler_type handler;
173+
+
174+
+ CustomSignalPendings[i] = false;
175+
+ handler = CustomHandlers[i];
176+
+ if (handler)
177+
+ handler();
178+
+ }
179+
+
180+
+ MemoryContextSwitchTo(oldcontext);
181+
+
182+
+ /* Might as well clear the context on our way out */
183+
+ MemoryContextReset(hcs_context);
184+
+
185+
+ RESUME_INTERRUPTS();
186+
+}
187+
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
188+
index 07b956553a..35c9da9d80 100644
189+
--- a/src/backend/tcop/postgres.c
190+
+++ b/src/backend/tcop/postgres.c
191+
@@ -3062,6 +3062,8 @@ ProcessInterrupts(void)
192+
193+
if (ParallelMessagePending)
194+
HandleParallelMessages();
195+
+
196+
+ CheckAndHandleCustomSignals();
197+
}
198+
199+
200+
diff --git a/src/include/storage/procsignal.h b/src/include/storage/procsignal.h
201+
index 6db0d69b71..b722a370ed 100644
202+
--- a/src/include/storage/procsignal.h
203+
+++ b/src/include/storage/procsignal.h
204+
@@ -17,6 +17,8 @@
205+
#include "storage/backendid.h"
206+
207+
208+
+#define NUM_CUSTOM_PROCSIGNALS 64
209+
+
210+
/*
211+
* Reasons for signalling a Postgres child process (a backend or an auxiliary
212+
* process, like checkpointer). We can cope with concurrent signals for different
213+
@@ -29,6 +31,8 @@
214+
*/
215+
typedef enum
216+
{
217+
+ INVALID_PROCSIGNAL = -1, /* Must be first */
218+
+
219+
PROCSIG_CATCHUP_INTERRUPT, /* sinval catchup interrupt */
220+
PROCSIG_NOTIFY_INTERRUPT, /* listen/notify interrupt */
221+
PROCSIG_PARALLEL_MESSAGE, /* message from cooperating parallel backend */
222+
@@ -42,9 +46,20 @@ typedef enum
223+
PROCSIG_RECOVERY_CONFLICT_BUFFERPIN,
224+
PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK,
225+
226+
+ PROCSIG_CUSTOM_1,
227+
+ /*
228+
+ * PROCSIG_CUSTOM_2,
229+
+ * ...,
230+
+ * PROCSIG_CUSTOM_N-1,
231+
+ */
232+
+ PROCSIG_CUSTOM_N = PROCSIG_CUSTOM_1 + NUM_CUSTOM_PROCSIGNALS - 1,
233+
+
234+
NUM_PROCSIGNALS /* Must be last! */
235+
} ProcSignalReason;
236+
237+
+/* Handler of custom process signal */
238+
+typedef void (*ProcSignalHandler_type) (void);
239+
+
240+
/*
241+
* prototypes for functions in procsignal.c
242+
*/
243+
@@ -52,9 +67,15 @@ extern Size ProcSignalShmemSize(void);
244+
extern void ProcSignalShmemInit(void);
245+
246+
extern void ProcSignalInit(int pss_idx);
247+
+extern ProcSignalReason RegisterCustomProcSignalHandler(ProcSignalHandler_type handler);
248+
+extern ProcSignalHandler_type AssignCustomProcSignalHandler(ProcSignalReason reason,
249+
+ ProcSignalHandler_type handler);
250+
+extern ProcSignalHandler_type GetCustomProcSignalHandler(ProcSignalReason reason);
251+
extern int SendProcSignal(pid_t pid, ProcSignalReason reason,
252+
BackendId backendId);
253+
254+
+extern void CheckAndHandleCustomSignals(void);
255+
+
256+
extern void procsignal_sigusr1_handler(SIGNAL_ARGS);
257+
258+
#endif /* PROCSIGNAL_H */

0 commit comments

Comments
 (0)