From e6e5447dc453788d0e9986cf191c91b8199f0ff3 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 on FreeBSD.

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

NB: This works on FreeBSD 12.0-CURRENT as of today, but the interface
might change.  It'll hopefully be nailed down and land in FreeBSD 11.2-RELEASE,
due out in June/July, in time for the first PostgreSQL 12 commitfest.
I'm sharing this patch now just to justify the way the macros are laid
out in the earlier patch, supporting more than one implementation of death
signals; it's also good for bleeding edge FreeBSD users to test.

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..894008e9af2 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_CTL, ...)
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <sys/procctl.h>
+
+int
+main ()
+{
+
+#ifndef PROC_PDEATHSIG_CTL
+#error PROC_PDEATHSIG_CTL not defined
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  HAVE_PROC_PDEATHSIG_CTL=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_CTL" = "x1"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: PROC_PDEATHSIG_CTL" >&5
+$as_echo "PROC_PDEATHSIG_CTL" >&6; }
+
+$as_echo "#define HAVE_PROC_PDEATHSIG_CTL 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..e19a1c645e9 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_CTL, ...)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
+#include <sys/procctl.h>
+], [
+#ifndef PROC_PDEATHSIG_CTL
+#error PROC_PDEATHSIG_CTL not defined
+#endif
+])], [HAVE_PROC_PDEATHSIG_CTL=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_CTL" = "x1"; then
+  AC_MSG_RESULT(PROC_PDEATHSIG_CTL)
+  AC_DEFINE(HAVE_PROC_PDEATHSIG_CTL, 1,
+            [Define to 1 if the system supports PROC_PDEATHSIG_CTL])
 else
   AC_MSG_RESULT(no)
 fi
diff --git a/src/backend/storage/ipc/pmsignal.c b/src/backend/storage/ipc/pmsignal.c
index 082da9351be..77065c39b13 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_CTL)
+#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 @@ PostmasterDeathSignalInit(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_CTL)
+	if (procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &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..4a0dccac559 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_CTL)
 #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..52103a86ef2 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_CTL */
+#undef HAVE_PROC_PDEATHSIG_CTL
+
 /* Define to 1 if the system supports PR_SET_PDEATHSIG */
 #undef HAVE_PR_SET_PDEATHSIG
 
-- 
2.16.2

