11diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
2- indexb9302ac..95f7da2 100644
2+ indexb9302ac630c..61871fe5cd5 100644
33--- a/src/backend/storage/ipc/procsignal.c
44+++ b/src/backend/storage/ipc/procsignal.c
55@@ -27,6 +27,7 @@
66 #include "storage/shmem.h"
77 #include "storage/sinval.h"
88 #include "tcop/tcopprot.h"
99+ #include "utils/memutils.h"
10-
11-
10+
11+
1212 /*
13- @@ -60,12 +61,17 @@ typedef struct
13+ @@ -60,12 +61,18 @@ typedef struct
1414 */
1515 #define NumProcSignalSlots(MaxBackends + NUM_AUXPROCTYPES)
16-
16+
1717+ static bool CustomSignalPendings[NUM_CUSTOM_PROCSIGNALS];
18+ + static bool CustomSignalProcessing[NUM_CUSTOM_PROCSIGNALS];
1819+ static ProcSignalHandler_type CustomHandlers[NUM_CUSTOM_PROCSIGNALS];
1920+
2021 static ProcSignalSlot *ProcSignalSlots = NULL;
2122 static volatile ProcSignalSlot *MyProcSignalSlot = NULL;
22-
23+
2324 static bool CheckProcSignal(ProcSignalReason reason);
2425 static void CleanupProcSignalState(int status, Datum arg);
25-
26+
2627+ static void CustomSignalInterrupt(ProcSignalReason reason);
2728+
2829 /*
2930 * ProcSignalShmemSize
3031 *Compute space needed for procsignal's shared memory
31- @@ -166,6 +172,57 @@ CleanupProcSignalState(int status, Datum arg)
32+ @@ -165,6 +172,57 @@ CleanupProcSignalState(int status, Datum arg)
33+ slot->pss_pid = 0;
3234 }
33-
34- /*
35+
36+ + /*
3537+ * RegisterCustomProcSignalHandler
3638+ * Assign specific handler for custom process signal with new ProcSignalReason key.
3739+ * Return INVALID_PROCSIGNAL if all custom signals have been assigned.
@@ -82,34 +84,33 @@ index b9302ac..95f7da2 100644
8284+ return CustomHandlers[reason - PROCSIG_CUSTOM_1];
8385+ }
8486+
85- + /*
87+ /*
8688 * SendProcSignal
8789 *Send a signal to a Postgres process
88- *
89- @@ -260,7 +317,8 @@ CheckProcSignal(ProcSignalReason reason)
90+ @@ -260,7 +318,8 @@ CheckProcSignal(ProcSignalReason reason)
9091 void
9192 procsignal_sigusr1_handler(SIGNAL_ARGS)
9293 {
9394- intsave_errno = errno;
9495+ intsave_errno = errno;
9596+ 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-
97+
98+ if (CheckProcSignal(PROCSIG_CATCHUP_INTERRUPT))
99+ HandleCatchupInterrupt();
100+ @@ -292,9 +351,81 @@ procsignal_sigusr1_handler(SIGNAL_ARGS)
101+ if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN))
102+ RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN);
103+
103104+ for (reason = PROCSIG_CUSTOM_1; reason <= PROCSIG_CUSTOM_N; reason++)
104105+ if (CheckProcSignal(reason))
105106+ CustomSignalInterrupt(reason);
106107+
107- SetLatch(MyLatch);
108-
109- latch_sigusr1_handler();
110-
111- errno = save_errno;
112- }
108+ SetLatch(MyLatch);
109+
110+ latch_sigusr1_handler();
111+
112+ errno = save_errno;
113+ }
113114+
114115+ /*
115116+ * Handle receipt of an interrupt indicating a custom process signal.
@@ -145,14 +146,6 @@ index b9302ac..95f7da2 100644
145146+ static MemoryContext hcs_context = NULL;
146147+
147148+ /*
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- + /*
156149+ * Moreover, CurrentMemoryContext might be pointing almost anywhere. We
157150+ * don't want to risk leaking data into long-lived contexts, so let's do
158151+ * our work here in a private context that we can reset on each use.
@@ -167,44 +160,46 @@ index b9302ac..95f7da2 100644
167160+ oldcontext = MemoryContextSwitchTo(hcs_context);
168161+
169162+ for (i = 0; i < NUM_CUSTOM_PROCSIGNALS; i++)
170- + if (CustomSignalPendings[i])
163+ + if (!CustomSignalProcessing[i] && CustomSignalPendings[i])
171164+ {
172165+ ProcSignalHandler_type handler;
173166+
174167+ CustomSignalPendings[i] = false;
175168+ handler = CustomHandlers[i];
176- + if (handler)
169+ + if (handler != NULL)
170+ + {
171+ + CustomSignalProcessing[i] = true;
177172+ handler();
173+ + CustomSignalProcessing[i] = false;
174+ + }
178175+ }
179176+
180177+ MemoryContextSwitchTo(oldcontext);
181178+
182179+ /* Might as well clear the context on our way out */
183180+ MemoryContextReset(hcs_context);
184- +
185- + RESUME_INTERRUPTS();
186181+ }
187182diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
188- index63a1994..0dfad33 100644
183+ index40413fa9039..70954e4deb2 100644
189184--- a/src/backend/tcop/postgres.c
190185+++ b/src/backend/tcop/postgres.c
191- @@ -3012 ,6 +3012 ,8 @@ ProcessInterrupts(void)
192-
193- if (ParallelMessagePending)
194- HandleParallelMessages();
186+ @@ -3063 ,6 +3063 ,8 @@ ProcessInterrupts(void)
187+
188+ if (ParallelMessagePending)
189+ HandleParallelMessages();
195190+
196191+ CheckAndHandleCustomSignals();
197192 }
198-
199-
193+
194+
200195diff --git a/src/include/storage/procsignal.h b/src/include/storage/procsignal.h
201- index20bb05b..9b16eb3 100644
196+ index20bb05b1779..9b16eb36fba 100644
202197--- a/src/include/storage/procsignal.h
203198+++ b/src/include/storage/procsignal.h
204199@@ -17,6 +17,8 @@
205200 #include "storage/backendid.h"
206-
207-
201+
202+
208203+ #define NUM_CUSTOM_PROCSIGNALS 64
209204+
210205 /*
@@ -216,13 +211,13 @@ index 20bb05b..9b16eb3 100644
216211 {
217212+ INVALID_PROCSIGNAL = -1,/* Must be first */
218213+
219- PROCSIG_CATCHUP_INTERRUPT,/* sinval catchup interrupt */
220- PROCSIG_NOTIFY_INTERRUPT,/* listen/notify interrupt */
221- PROCSIG_PARALLEL_MESSAGE,/* message from cooperating parallel backend */
214+ PROCSIG_CATCHUP_INTERRUPT,/* sinval catchup interrupt */
215+ PROCSIG_NOTIFY_INTERRUPT,/* listen/notify interrupt */
216+ PROCSIG_PARALLEL_MESSAGE,/* message from cooperating parallel backend */
222217@@ -42,9 +46,20 @@ typedef enum
223- PROCSIG_RECOVERY_CONFLICT_BUFFERPIN,
224- PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK,
225-
218+ PROCSIG_RECOVERY_CONFLICT_BUFFERPIN,
219+ PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK,
220+
226221+ PROCSIG_CUSTOM_1,
227222+ /*
228223+ * PROCSIG_CUSTOM_2,
@@ -231,9 +226,9 @@ index 20bb05b..9b16eb3 100644
231226+ */
232227+ PROCSIG_CUSTOM_N = PROCSIG_CUSTOM_1 + NUM_CUSTOM_PROCSIGNALS - 1,
233228+
234- NUM_PROCSIGNALS/* Must be last! */
229+ NUM_PROCSIGNALS/* Must be last! */
235230 } ProcSignalReason;
236-
231+
237232+ /* Handler of custom process signal */
238233+ typedef void (*ProcSignalHandler_type) (void);
239234+
@@ -242,17 +237,19 @@ index 20bb05b..9b16eb3 100644
242237 */
243238@@ -52,9 +67,15 @@ extern Size ProcSignalShmemSize(void);
244239 extern void ProcSignalShmemInit(void);
245-
240+
246241 extern void ProcSignalInit(int pss_idx);
247242+ extern ProcSignalReason RegisterCustomProcSignalHandler(ProcSignalHandler_type handler);
248243+ extern ProcSignalHandler_type AssignCustomProcSignalHandler(ProcSignalReason reason,
249244+ ProcSignalHandler_type handler);
250245+ extern ProcSignalHandler_type GetCustomProcSignalHandler(ProcSignalReason reason);
251246 extern int SendProcSignal(pid_t pid, ProcSignalReason reason,
252- BackendId backendId);
253-
247+ BackendId backendId);
248+
254249+ extern void CheckAndHandleCustomSignals(void);
255250+
256251 extern void procsignal_sigusr1_handler(SIGNAL_ARGS);
257-
252+
258253 #endif/* PROCSIGNAL_H */
254+ - -
255+ 2.25.1