11diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
2- index 4fa385b0ece..fc1637a2e28 100644
2+ index 4fa385b0ece..60854eee386 100644
33--- a/src/backend/storage/ipc/procsignal.c
44+++ b/src/backend/storage/ipc/procsignal.c
55@@ -88,12 +88,21 @@ typedef struct
6- (((flags) & (((uint32) 1) << (uint32) (type))) != 0)
7-
6+ (((flags) & (((uint32) 1) << (uint32) (type))) != 0)
7+
88 static ProcSignalHeader *ProcSignal = NULL;
99+ #define IsCustomProcSignalReason(reason) \
1010+ ((reason) >= PROCSIG_CUSTOM_1 && (reason) <= PROCSIG_CUSTOM_N)
@@ -14,20 +14,20 @@ index 4fa385b0ece..fc1637a2e28 100644
1414+ static ProcSignalHandler_type CustomInterruptHandlers[NUM_CUSTOM_PROCSIGNALS];
1515+
1616 static volatile ProcSignalSlot *MyProcSignalSlot = NULL;
17-
17+
1818 static bool CheckProcSignal(ProcSignalReason reason);
1919 static void CleanupProcSignalState(int status, Datum arg);
2020 static void ProcessBarrierPlaceholder(void);
21-
21+
2222+ static void CheckAndSetCustomSignalInterrupts(void);
2323+
2424 /*
2525 * ProcSignalShmemSize
2626 *Compute space needed for procsignal's shared memory
2727@@ -235,6 +244,36 @@ CleanupProcSignalState(int status, Datum arg)
28- slot->pss_pid = 0;
28+ slot->pss_pid = 0;
2929 }
30-
30+
3131+ /*
3232+ * RegisterCustomProcSignalHandler
3333+ *Assign specific handler of custom process signal with new
@@ -61,17 +61,17 @@ index 4fa385b0ece..fc1637a2e28 100644
6161 /*
6262 * SendProcSignal
6363 *Send a signal to a Postgres process
64- @@ -585,9 +624,64 @@ procsignal_sigusr1_handler(SIGNAL_ARGS)
65- if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN))
66- RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN);
67-
64+ @@ -585,9 +624,71 @@ procsignal_sigusr1_handler(SIGNAL_ARGS)
65+ if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN))
66+ RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN);
67+
6868+ CheckAndSetCustomSignalInterrupts();
6969+
70- SetLatch(MyLatch);
71-
72- latch_sigusr1_handler();
73-
74- errno = save_errno;
70+ SetLatch(MyLatch);
71+
72+ latch_sigusr1_handler();
73+
74+ errno = save_errno;
7575 }
7676+
7777+ /*
@@ -108,9 +108,15 @@ index 4fa385b0ece..fc1637a2e28 100644
108108+ {
109109+ int i;
110110+
111- + /* Check on expiring of custom signals and call its handlers if exist */
111+ + /*
112+ + * This is invoked from ProcessInterrupts(), and since some of the
113+ + * functions it calls contain CHECK_FOR_INTERRUPTS(), there is a potential
114+ + * for recursive calls if more signals are received while this runs, so
115+ + * let's block interrupts until done.
116+ + */
117+ + HOLD_INTERRUPTS();
118+ +
112119+ for (i = 0; i < NUM_CUSTOM_PROCSIGNALS; i++)
113- + {
114120+ if (!CustomSignalProcessing[i] && CustomSignalPendings[i])
115121+ {
116122+ ProcSignalHandler_type handler;
@@ -124,29 +130,66 @@ index 4fa385b0ece..fc1637a2e28 100644
124130+ CustomSignalProcessing[i] = false;
125131+ }
126132+ }
127- + }
133+ +
134+ + RESUME_INTERRUPTS();
128135+ }
129136diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
130- index174c72a14bc..0e7366bd58f 100644
137+ index7bc03ae4edc..3debd63bd7d 100644
131138--- a/src/backend/tcop/postgres.c
132139+++ b/src/backend/tcop/postgres.c
133- @@ -3221,6 +3221,8 @@ ProcessInterrupts(void)
134-
135- if (ParallelMessagePending)
136- HandleParallelMessages();
140+ @@ -5,6 +5,7 @@
141+ *
142+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
143+ * Portions Copyright (c) 1994, Regents of the University of California
144+ + * Portions Copyright (c) 2020-2021, Postgres Professional
145+ *
146+ *
147+ * IDENTIFICATION
148+ @@ -74,6 +75,7 @@
149+ #include "tcop/pquery.h"
150+ #include "tcop/tcopprot.h"
151+ #include "tcop/utility.h"
152+ + #include "utils/builtins.h"
153+ #include "utils/lsyscache.h"
154+ #include "utils/memutils.h"
155+ #include "utils/ps_status.h"
156+ @@ -3231,6 +3233,8 @@ ProcessInterrupts(void)
157+
158+ if (ParallelMessagePending)
159+ HandleParallelMessages();
137160+
138161+ CheckAndHandleCustomSignals();
139162 }
140-
141-
163+
164+
165+ @@ -3576,7 +3580,7 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx,
166+ * postmaster/postmaster.c (the option sets should not conflict) and with
167+ * the common help() function in main/main.c.
168+ */
169+ - while ((flag = getopt(argc, argv, "B:bc:C:D:d:EeFf:h:ijk:lN:nOo:Pp:r:S:sTt:v:W:-:")) != -1)
170+ + while ((flag = getopt(argc, argv, "B:bc:C:D:d:EeFf:h:ijk:lN:nOo:Pp:r:S:sTt:v:W:Z-:")) != -1)
171+ {
172+ switch (flag)
173+ {
174+ @@ -3712,6 +3716,10 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx,
175+ SetConfigOption("post_auth_delay", optarg, ctx, gucsource);
176+ break;
177+
178+ + case 'Z':
179+ + /* ignored for consistency with the postmaster */
180+ + break;
181+ +
182+ case 'c':
183+ case '-':
184+ {
142185diff --git a/src/include/storage/procsignal.h b/src/include/storage/procsignal.h
143186index 5cb39697f38..c05f60fa719 100644
144187--- a/src/include/storage/procsignal.h
145188+++ b/src/include/storage/procsignal.h
146189@@ -17,6 +17,8 @@
147190 #include "storage/backendid.h"
148-
149-
191+
192+
150193+ #define NUM_CUSTOM_PROCSIGNALS 64
151194+
152195 /*
@@ -158,13 +201,13 @@ index 5cb39697f38..c05f60fa719 100644
158201 {
159202+ INVALID_PROCSIGNAL = -1,/* Must be first */
160203+
161- PROCSIG_CATCHUP_INTERRUPT,/* sinval catchup interrupt */
162- PROCSIG_NOTIFY_INTERRUPT,/* listen/notify interrupt */
163- PROCSIG_PARALLEL_MESSAGE,/* message from cooperating parallel backend */
204+ PROCSIG_CATCHUP_INTERRUPT,/* sinval catchup interrupt */
205+ PROCSIG_NOTIFY_INTERRUPT,/* listen/notify interrupt */
206+ PROCSIG_PARALLEL_MESSAGE,/* message from cooperating parallel backend */
164207@@ -43,6 +47,14 @@ typedef enum
165- PROCSIG_RECOVERY_CONFLICT_BUFFERPIN,
166- PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK,
167-
208+ PROCSIG_RECOVERY_CONFLICT_BUFFERPIN,
209+ PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK,
210+
168211+ PROCSIG_CUSTOM_1,
169212+ /*
170213+ * PROCSIG_CUSTOM_2,
@@ -173,34 +216,31 @@ index 5cb39697f38..c05f60fa719 100644
173216+ */
174217+ PROCSIG_CUSTOM_N = PROCSIG_CUSTOM_1 + NUM_CUSTOM_PROCSIGNALS - 1,
175218+
176- NUM_PROCSIGNALS/* Must be last! */
219+ NUM_PROCSIGNALS/* Must be last! */
177220 } ProcSignalReason;
178-
221+
179222@@ -55,6 +67,8 @@ typedef enum
180- */
181- PROCSIGNAL_BARRIER_PLACEHOLDER = 0
223+ */
224+ PROCSIGNAL_BARRIER_PLACEHOLDER = 0
182225 } ProcSignalBarrierType;
183226+ /* Handler of custom process signal */
184227+ typedef void (*ProcSignalHandler_type) (void);
185-
228+
186229 /*
187230 * prototypes for functions in procsignal.c
188231@@ -63,12 +77,15 @@ extern Size ProcSignalShmemSize(void);
189232 extern void ProcSignalShmemInit(void);
190-
233+
191234 extern void ProcSignalInit(int pss_idx);
192235+ extern ProcSignalReason
193236+ RegisterCustomProcSignalHandler(ProcSignalHandler_type handler);
194237 extern intSendProcSignal(pid_t pid, ProcSignalReason reason,
195- BackendId backendId);
196-
238+ BackendId backendId);
239+
197240 extern uint64 EmitProcSignalBarrier(ProcSignalBarrierType type);
198241 extern void WaitForProcSignalBarrier(uint64 generation);
199242 extern void ProcessProcSignalBarrier(void);
200243+ extern void CheckAndHandleCustomSignals(void);
201-
244+
202245 extern void procsignal_sigusr1_handler(SIGNAL_ARGS);
203-
204- - -
205- 2.25.1
206-
246+