commit 8ef025fb5c3eaf2f91479bf2a0bc7ea855dddb42
Author: Chris Traverswq <chris.travers@gmail.com>
Date:   Thu Sep 20 13:55:25 2018 +0200

    Refactoring some signal checks.
    
    In the past the areas I refactored checked signal status using global flags directly.
    This makes it hard to follow code, and reason about correctness.  So I introduced a minor
    refactoring to ensure that interrupt level can be detected and processed without worrying about internals.

diff --git a/src/backend/regex/regcomp.c b/src/backend/regex/regcomp.c
index eb1f3d57a8..4a8c2bf63f 100644
--- a/src/backend/regex/regcomp.c
+++ b/src/backend/regex/regcomp.c
@@ -33,6 +33,7 @@
  */
 
 #include "regex/regguts.h"
+#include "miscadmin.h"
 
 /*
  * forward declarations, up here so forward datatypes etc. are defined early
@@ -2015,7 +2016,7 @@ rfree(regex_t *re)
 static int
 rcancelrequested(void)
 {
-	return InterruptPending && (QueryCancelPending || ProcDiePending);
+	return PENDING_INTERRUPT_LEVEL() >= QUERY_CANCEL;
 }
 
 /*
diff --git a/src/backend/storage/ipc/dsm_impl.c b/src/backend/storage/ipc/dsm_impl.c
index 70f899e765..1f21590237 100644
--- a/src/backend/storage/ipc/dsm_impl.c
+++ b/src/backend/storage/ipc/dsm_impl.c
@@ -436,7 +436,7 @@ dsm_impl_posix_resize(int fd, off_t size)
 		do
 		{
 			rc = posix_fallocate(fd, 0, size);
-		} while (rc == EINTR && !(ProcDiePending || QueryCancelPending));
+		} while (rc == EINTR && (PENDING_INTERRUPT_LEVEL() < QUERY_CANCEL))
 
 		/*
 		 * The caller expects errno to be set, but posix_fallocate() doesn't
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index e167ee8fcb..ec8b5a51b7 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -137,6 +137,35 @@ do { \
 } while(0)
 
 
+enum PendingInterruptLevel {
+     NO_INTERRUPT,
+     INTERRUPT,
+     QUERY_CANCEL,
+     PROCESS_EXIT
+};
+
+
+/* PENDING_INTERRUPT_LEVEL() returns effectively a PendingInterruptLevel enum
+ * value.  The function is used to determine what the expected impact of
+ * calling CHECK_FOR_INTERRUPTS() will likely be.  This is usually done
+ * in order to handle errors and cleanup code as needed.
+ *
+ * The levels offered are:
+ * 
+ *  Level                   Meaning
+ *  NO_INTERRUPT            No interrupt is pending
+ *  INTERRUPT               A non-cancelling interrupt needs to be handled
+ *  QUERY_CANCEL            A query cancellation, but not a process exit
+ *  PROCESS_EXIT            The process is to be terminated
+ */
+
+#define PENDING_INTERRUPT_LEVEL() (\
+    ProcDiePending     ? PROCESS_EXIT : \
+     (QueryCancelPending ? QUERY_CANCEL : \
+       (InterruptPending ? INTERRUPT: NO_INTERRUPT)\
+     )\
+    )
+
 /*****************************************************************************
  *	  globals.h --															 *
  *****************************************************************************/
