From 1e027111dac326fa34138c1451e6b6d9dd222489 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.

NOT FOR COMMIT: Support on the FreeBSD side is committed but not yet shipped
and could change.  There is a chance it'll ship before CF1, in FreeBSD 11.2.
Sharing this patch now 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

