commit 8ef025fb5c3eaf2f91479bf2a0bc7ea855dddb42 Author: Chris Traverswq 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 -- * *****************************************************************************/