Skip to content

Commit 1a5283c

Browse files
authored
Merge pull request #14 from ololobus/master
Add core patches for Postgres v12
2 parents c00cfed + 367aa15 commit 1a5283c

File tree

2 files changed

+477
-0
lines changed

2 files changed

+477
-0
lines changed

patches/custom_signals_12.0.patch

+213
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
From 44e4d28abd0a63a6e1c4a75c55ad27fb827dbfa4 Mon Sep 17 00:00:00 2001
2+
From: Alexey Kondratov <kondratov.aleksey@gmail.com>
3+
Date: Fri, 18 Oct 2019 19:44:01 +0300
4+
Subject: [PATCH] [custom_signals] Allow extensions to set custom signal
5+
handlers
6+
7+
---
8+
src/backend/storage/ipc/procsignal.c | 94 ++++++++++++++++++++++++++++
9+
src/backend/tcop/postgres.c | 2 +
10+
src/include/storage/procsignal.h | 19 ++++++
11+
3 files changed, 115 insertions(+)
12+
13+
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
14+
index 7605b2c3674..0802ed1119b 100644
15+
--- a/src/backend/storage/ipc/procsignal.c
16+
+++ b/src/backend/storage/ipc/procsignal.c
17+
@@ -60,12 +60,20 @@ typedef struct
18+
*/
19+
#define NumProcSignalSlots (MaxBackends + NUM_AUXPROCTYPES)
20+
21+
+#define IsCustomProcSignalReason(reason) \
22+
+ ((reason) >= PROCSIG_CUSTOM_1 && (reason) <= PROCSIG_CUSTOM_N)
23+
+
24+
+static bool CustomSignalPendings[NUM_CUSTOM_PROCSIGNALS];
25+
+static ProcSignalHandler_type CustomInterruptHandlers[NUM_CUSTOM_PROCSIGNALS];
26+
+
27+
static ProcSignalSlot *ProcSignalSlots = NULL;
28+
static volatile ProcSignalSlot *MyProcSignalSlot = NULL;
29+
30+
static bool CheckProcSignal(ProcSignalReason reason);
31+
static void CleanupProcSignalState(int status, Datum arg);
32+
33+
+static void CheckAndSetCustomSignalInterrupts(void);
34+
+
35+
/*
36+
* ProcSignalShmemSize
37+
* Compute space needed for procsignal's shared memory
38+
@@ -165,6 +173,36 @@ CleanupProcSignalState(int status, Datum arg)
39+
slot->pss_pid = 0;
40+
}
41+
42+
+/*
43+
+ * RegisterCustomProcSignalHandler
44+
+ * Assign specific handler of custom process signal with new
45+
+ * ProcSignalReason key.
46+
+ *
47+
+ * This function has to be called in _PG_init function of extensions at the
48+
+ * stage of loading shared preloaded libraries. Otherwise it throws fatal error.
49+
+ *
50+
+ * Return INVALID_PROCSIGNAL if all slots for custom signals are occupied.
51+
+ */
52+
+ProcSignalReason
53+
+RegisterCustomProcSignalHandler(ProcSignalHandler_type handler)
54+
+{
55+
+ ProcSignalReason reason;
56+
+
57+
+ if (!process_shared_preload_libraries_in_progress)
58+
+ ereport(FATAL, (errcode(ERRCODE_INTERNAL_ERROR),
59+
+ errmsg("cannot register custom signal after startup")));
60+
+
61+
+ /* Iterate through custom signal slots to find a free one */
62+
+ for (reason = PROCSIG_CUSTOM_1; reason <= PROCSIG_CUSTOM_N; reason++)
63+
+ if (!CustomInterruptHandlers[reason - PROCSIG_CUSTOM_1])
64+
+ {
65+
+ CustomInterruptHandlers[reason - PROCSIG_CUSTOM_1] = handler;
66+
+ return reason;
67+
+ }
68+
+
69+
+ return INVALID_PROCSIGNAL;
70+
+}
71+
+
72+
/*
73+
* SendProcSignal
74+
* Send a signal to a Postgres process
75+
@@ -292,9 +330,65 @@ procsignal_sigusr1_handler(SIGNAL_ARGS)
76+
if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN))
77+
RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN);
78+
79+
+ CheckAndSetCustomSignalInterrupts();
80+
+
81+
SetLatch(MyLatch);
82+
83+
latch_sigusr1_handler();
84+
85+
errno = save_errno;
86+
}
87+
+
88+
+/*
89+
+ * Handle receipt of an interrupt indicating any of custom process signals.
90+
+ */
91+
+static void
92+
+CheckAndSetCustomSignalInterrupts()
93+
+{
94+
+ ProcSignalReason reason;
95+
+
96+
+ for (reason = PROCSIG_CUSTOM_1; reason <= PROCSIG_CUSTOM_N; reason++)
97+
+ {
98+
+ if (CheckProcSignal(reason))
99+
+ {
100+
+
101+
+ /* set interrupt flags */
102+
+ InterruptPending = true;
103+
+ CustomSignalPendings[reason - PROCSIG_CUSTOM_1] = true;
104+
+ }
105+
+ }
106+
+
107+
+ SetLatch(MyLatch);
108+
+}
109+
+
110+
+/*
111+
+ * CheckAndHandleCustomSignals
112+
+ * Check custom signal flags and call handler assigned to that signal
113+
+ * if it is not NULL
114+
+ *
115+
+ * This function is called within CHECK_FOR_INTERRUPTS if interrupt occurred.
116+
+ */
117+
+void
118+
+CheckAndHandleCustomSignals(void)
119+
+{
120+
+ int i;
121+
+
122+
+ /* Disable interrupts to avoid recursive calls */
123+
+ HOLD_INTERRUPTS();
124+
+
125+
+ /* Check on expiring of custom signals and call its handlers if exist */
126+
+ for (i = 0; i < NUM_CUSTOM_PROCSIGNALS; i++)
127+
+ if (CustomSignalPendings[i])
128+
+ {
129+
+ ProcSignalHandler_type handler;
130+
+ ProcSignalReason reason;
131+
+
132+
+ CustomSignalPendings[i] = false;
133+
+ handler = CustomInterruptHandlers[i];
134+
+ reason = PROCSIG_CUSTOM_1 + i;
135+
+ if (handler != NULL)
136+
+ handler(reason);
137+
+ }
138+
+
139+
+ RESUME_INTERRUPTS();
140+
+}
141+
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
142+
index c28cc370129..f5a48b98e86 100644
143+
--- a/src/backend/tcop/postgres.c
144+
+++ b/src/backend/tcop/postgres.c
145+
@@ -3139,6 +3139,8 @@ ProcessInterrupts(void)
146+
147+
if (ParallelMessagePending)
148+
HandleParallelMessages();
149+
+
150+
+ CheckAndHandleCustomSignals();
151+
}
152+
153+
154+
diff --git a/src/include/storage/procsignal.h b/src/include/storage/procsignal.h
155+
index 05b186a05c2..84290d60975 100644
156+
--- a/src/include/storage/procsignal.h
157+
+++ b/src/include/storage/procsignal.h
158+
@@ -17,6 +17,8 @@
159+
#include "storage/backendid.h"
160+
161+
162+
+#define NUM_CUSTOM_PROCSIGNALS 64
163+
+
164+
/*
165+
* Reasons for signalling a Postgres child process (a backend or an auxiliary
166+
* process, like checkpointer). We can cope with concurrent signals for different
167+
@@ -29,6 +31,8 @@
168+
*/
169+
typedef enum
170+
{
171+
+ INVALID_PROCSIGNAL = -1, /* Must be first */
172+
+
173+
PROCSIG_CATCHUP_INTERRUPT, /* sinval catchup interrupt */
174+
PROCSIG_NOTIFY_INTERRUPT, /* listen/notify interrupt */
175+
PROCSIG_PARALLEL_MESSAGE, /* message from cooperating parallel backend */
176+
@@ -42,9 +46,20 @@ typedef enum
177+
PROCSIG_RECOVERY_CONFLICT_BUFFERPIN,
178+
PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK,
179+
180+
+ PROCSIG_CUSTOM_1,
181+
+ /*
182+
+ * PROCSIG_CUSTOM_2,
183+
+ * ...,
184+
+ * PROCSIG_CUSTOM_N-1,
185+
+ */
186+
+ PROCSIG_CUSTOM_N = PROCSIG_CUSTOM_1 + NUM_CUSTOM_PROCSIGNALS - 1,
187+
+
188+
NUM_PROCSIGNALS /* Must be last! */
189+
} ProcSignalReason;
190+
191+
+/* Handler of custom process signal */
192+
+typedef void (*ProcSignalHandler_type) (ProcSignalReason reason);
193+
+
194+
/*
195+
* prototypes for functions in procsignal.c
196+
*/
197+
@@ -52,9 +67,13 @@ extern Size ProcSignalShmemSize(void);
198+
extern void ProcSignalShmemInit(void);
199+
200+
extern void ProcSignalInit(int pss_idx);
201+
+extern ProcSignalReason
202+
+ RegisterCustomProcSignalHandler(ProcSignalHandler_type handler);
203+
extern int SendProcSignal(pid_t pid, ProcSignalReason reason,
204+
BackendId backendId);
205+
206+
+extern void CheckAndHandleCustomSignals(void);
207+
+
208+
extern void procsignal_sigusr1_handler(SIGNAL_ARGS);
209+
210+
#endif /* PROCSIGNAL_H */
211+
--
212+
2.17.1
213+

0 commit comments

Comments
 (0)