From 591a65113fb94b9d8335a0f0fbc6ab1349b68511 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@enterprisedb.com>
Date: Wed, 10 Oct 2018 13:20:54 +1300
Subject: [PATCH 1/2] Add proc_die_hook to customize die() interrupt handling.

Background workers using the standard die() SIGTERM handler currently
exit with a FATAL error message at their next CHECK_FOR_INTERRUPTS().
Provide a way for any backend to install an alternative handler.

Provide a function proc_die_quietly() that can be installed to exit
without raising an error in that case.

Author: Thomas Munro, based on a suggestion from Robert Haas
Discussion: https://postgr.es/m/CA%2BTgmobwExL4kNj_eXJxPah_tVQ31N0cYDbUN0FFm6uaY_%2BX%3Dw%40mail.gmail.com
---
 src/backend/tcop/postgres.c | 29 +++++++++++++++++++++++++----
 src/include/tcop/tcopprot.h |  2 ++
 2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index e4c6e3d406e..743f8a89a58 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -100,6 +100,9 @@ int			max_stack_depth = 100;
 /* wait N seconds to allow attach from a debugger */
 int			PostAuthDelay = 0;
 
+/* Hook for custom proc die handler. */
+void		(*proc_die_hook)(void);
+
 
 
 /* ----------------
@@ -2989,10 +2992,17 @@ ProcessInterrupts(void)
 					 errmsg("terminating connection due to conflict with recovery"),
 					 errdetail_recovery_conflict()));
 		}
-		else
-			ereport(FATAL,
-					(errcode(ERRCODE_ADMIN_SHUTDOWN),
-					 errmsg("terminating connection due to administrator command")));
+		else if (proc_die_hook)
+		{
+			/*
+			 * Custom proc die callback, which is expected to call proc_exit()
+			 * or ereport(FATAL, ...).
+			 */
+			(*proc_die_hook)();
+		}
+		ereport(FATAL,
+				(errcode(ERRCODE_ADMIN_SHUTDOWN),
+				 errmsg("terminating connection due to administrator command")));
 	}
 	if (ClientConnectionLost)
 	{
@@ -3125,6 +3135,17 @@ ProcessInterrupts(void)
 		HandleParallelMessages();
 }
 
+/*
+ * A function installable as proc_die_hook, for backends such as bgworkers
+ * that wish to exit from ProcessInterrupts() quietly after SIGTERM is
+ * received by the standard die() handler.
+ */
+void
+proc_die_quietly(void)
+{
+	proc_exit(0);
+}
+
 
 /*
  * IA64-specific code to fetch the AR.BSP register for stack depth checks.
diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h
index 63b4e4864d0..827a0f19dd4 100644
--- a/src/include/tcop/tcopprot.h
+++ b/src/include/tcop/tcopprot.h
@@ -34,6 +34,7 @@ extern CommandDest whereToSendOutput;
 extern PGDLLIMPORT const char *debug_query_string;
 extern int	max_stack_depth;
 extern int	PostAuthDelay;
+extern void (*proc_die_hook)(void);
 
 /* GUC-configurable parameters */
 
@@ -65,6 +66,7 @@ extern List *pg_plan_queries(List *querytrees, int cursorOptions,
 extern bool check_max_stack_depth(int *newval, void **extra, GucSource source);
 extern void assign_max_stack_depth(int newval, void *extra);
 
+extern void proc_die_quietly(void);
 extern void die(SIGNAL_ARGS);
 extern void quickdie(SIGNAL_ARGS) pg_attribute_noreturn();
 extern void StatementCancelHandler(SIGNAL_ARGS);
-- 
2.17.1 (Apple Git-112)

