From a7b5825fa100cb97fdaf2565a6cd9f3203688806 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@enterprisedb.com>
Date: Wed, 18 Apr 2018 16:17:54 +1200
Subject: [PATCH 2/2] Use signals for postmaster death detection on FreeBSD.

Use FreeBSD's new support for detecting parent process death to make
PostmasterIsAlive() very cheap, as was done earlier for Linux.

NOT FOR COMMIT: waiting for https://reviews.freebsd.org/D15106 to land.
Sharing this patch just to justify the way the macros are laid out in the
earlier patch, to support future implementations.

Author: Thomas Munro
Discussion: https://postgr.es/m/7261eb39-0369-f2f4-1bb5-62f3b6083b5e@iki.fi
---
 configure                          | 29 +++++++++++++++++++++++++++++
 configure.in                       | 13 +++++++++++++
 src/backend/storage/ipc/pmsignal.c |  7 +++++++
 src/include/c.h                    |  2 +-
 src/include/pg_config.h.in         |  3 +++
 5 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 29ba38ee174..ad3455be1f2 100755
--- a/configure
+++ b/configure
@@ -9746,12 +9746,41 @@ if ac_fn_c_try_compile "$LINENO"; then :
 fi
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
+# FreeBSD 12.0 has procctl(..., PROC_PDEATHSIG_SET, ...)
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <sys/procctl.h>
+
+int
+main ()
+{
+
+#ifndef PROC_PDEATHSIG_SET
+#error PROC_PDEATHSIG_SET not defined
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  HAVE_PROC_PDEATHSIG_SET=1
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
 if test x"$HAVE_PR_SET_PDEATHSIG" = "x1"; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: PR_SET_PDEATHSIG" >&5
 $as_echo "PR_SET_PDEATHSIG" >&6; }
 
 $as_echo "#define HAVE_PR_SET_PDEATHSIG 1" >>confdefs.h
 
+elif test x"$HAVE_PROC_PDEATHSIG_SET" = "x1"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: PROC_PDEATHSIG_SET" >&5
+$as_echo "PROC_PDEATHSIG_SET" >&6; }
+
+$as_echo "#define HAVE_PROC_PDEATHSIG_SET 1" >>confdefs.h
+
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
diff --git a/configure.in b/configure.in
index 31dda503628..5cb111580be 100644
--- a/configure.in
+++ b/configure.in
@@ -1036,10 +1036,23 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
 #endif
 ])], [HAVE_PR_SET_PDEATHSIG=1])
 
+# FreeBSD 12.0 has procctl(..., PROC_PDEATHSIG_SET, ...)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
+#include <sys/procctl.h>
+], [
+#ifndef PROC_PDEATHSIG_SET
+#error PROC_PDEATHSIG_SET not defined
+#endif
+])], [HAVE_PROC_PDEATHSIG_SET=1])
+
 if test x"$HAVE_PR_SET_PDEATHSIG" = "x1"; then
   AC_MSG_RESULT(PR_SET_PDEATHSIG)
   AC_DEFINE(HAVE_PR_SET_PDEATHSIG, 1,
             [Define to 1 if the system supports PR_SET_PDEATHSIG])
+elif test x"$HAVE_PROC_PDEATHSIG_SET" = "x1"; then
+  AC_MSG_RESULT(PROC_PDEATHSIG_SET)
+  AC_DEFINE(HAVE_PROC_PDEATHSIG_SET, 1,
+            [Define to 1 if the system supports PROC_PDEATHSIG_SET])
 else
   AC_MSG_RESULT(no)
 fi
diff --git a/src/backend/storage/ipc/pmsignal.c b/src/backend/storage/ipc/pmsignal.c
index c415b8b5dbb..2f53da43975 100644
--- a/src/backend/storage/ipc/pmsignal.c
+++ b/src/backend/storage/ipc/pmsignal.c
@@ -27,6 +27,10 @@
 #include <sys/prctl.h>
 #endif
 
+#if defined(HAVE_PROC_PDEATHSIG_SET)
+#include <sys/procctl.h>
+#endif
+
 /*
  * The postmaster is signaled by its children by sending SIGUSR1.  The
  * specific reason is communicated via flags in shared memory.  We keep
@@ -334,6 +338,9 @@ PostmasterDeathInit(void)
 #ifdef HAVE_PR_SET_PDEATHSIG
 	if (prctl(PR_SET_PDEATHSIG, signum) < 0)
 		elog(ERROR, "could not request parent death signal: %m");
+#elif defined(HAVE_PROC_PDEATHSIG_SET)
+	if (procctl(P_PID, 0, PROC_PDEATHSIG_SET, &signum) < 0)
+		elog(ERROR, "could not request parent death signal: %m");
 #endif
 
 	/*
diff --git a/src/include/c.h b/src/include/c.h
index 116c2a24814..16083afca55 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -1161,7 +1161,7 @@ extern int	fdatasync(int fildes);
  * platforms that support it, for testing purposes.
  */
 #ifndef NO_POSTMASTER_DEATH_SIGNAL
-#if defined(HAVE_PR_SET_PDEATHSIG)
+#if defined(HAVE_PR_SET_PDEATHSIG) || defined(HAVE_PROC_PDEATHSIG_SET)
 #define USE_POSTMASTER_DEATH_SIGNAL
 #endif
 #endif
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 5454f0d4807..941fe301b82 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -428,6 +428,9 @@
 /* Define to 1 if the assembler supports PPC's LWARX mutex hint bit. */
 #undef HAVE_PPC_LWARX_MUTEX_HINT
 
+/* Define to 1 if the system supports PROC_PDEATHSIG_SET */
+#undef HAVE_PROC_PDEATHSIG_SET
+
 /* Define to 1 if the system supports PR_SET_PDEATHSIG */
 #undef HAVE_PR_SET_PDEATHSIG
 
-- 
2.16.2

