summaryrefslogtreecommitdiff
path: root/src/backend/libpq/be-secure.c
diff options
context:
space:
mode:
authorTom Lane2018-10-20 01:39:21 +0000
committerTom Lane2018-10-20 01:39:21 +0000
commit2ddb9149d14de9a2e7ac9ec6accf3ad442702b24 (patch)
tree41dbed01032da06d1943a4a5dbb1c06ae1508b94 /src/backend/libpq/be-secure.c
parent12bfb778ce688fc662a6cb35f6298734fcf4856f (diff)
Server-side fix for delayed NOTIFY and SIGTERM processing.
Commit 4f85fde8e introduced some code that was meant to ensure that we'd process cancel, die, sinval catchup, and notify interrupts while waiting for client input. But there was a flaw: it supposed that the process latch would be set upon arrival at secure_read() if any such interrupt was pending. In reality, we might well have cleared the process latch at some earlier point while those flags remained set -- particularly notifyInterruptPending, which can't be handled as long as we're within a transaction. To fix the NOTIFY case, also attempt to process signals (except ProcDiePending) before trying to read. Also, if we see that ProcDiePending is set before we read, forcibly set the process latch to ensure that we will handle that signal promptly if no data is available. I also made it set the process latch on the way out, in case there is similar logic elsewhere. (It remains true that we won't service ProcDiePending here unless we need to wait for input.) The code for handling ProcDiePending during a write needs those changes, too. Also be a little more careful about when to reset whereToSendOutput, and improve related comments. Back-patch to 9.5 where this code was added. I'm not entirely convinced that older branches don't have similar issues, but the complaint at hand is just about the >= 9.5 code. Jeff Janes and Tom Lane Discussion: https://postgr.es/m/CAOYf6ec-TmRYjKBXLLaGaB-jrd=mjG1Hzn1a1wufUAR39PQYhw@mail.gmail.com
Diffstat (limited to 'src/backend/libpq/be-secure.c')
-rw-r--r--src/backend/libpq/be-secure.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
index d349d7c2c72..4eb21fe89de 100644
--- a/src/backend/libpq/be-secure.c
+++ b/src/backend/libpq/be-secure.c
@@ -145,6 +145,9 @@ secure_read(Port *port, void *ptr, size_t len)
ssize_t n;
int waitfor;
+ /* Deal with any already-pending interrupt condition. */
+ ProcessClientReadInterrupt(false);
+
retry:
#ifdef USE_SSL
waitfor = 0;
@@ -209,9 +212,8 @@ retry:
}
/*
- * Process interrupts that happened while (or before) receiving. Note that
- * we signal that we're not blocking, which will prevent some types of
- * interrupts from being processed.
+ * Process interrupts that happened during a successful (or non-blocking,
+ * or hard-failed) read.
*/
ProcessClientReadInterrupt(false);
@@ -248,6 +250,9 @@ secure_write(Port *port, void *ptr, size_t len)
ssize_t n;
int waitfor;
+ /* Deal with any already-pending interrupt condition. */
+ ProcessClientWriteInterrupt(false);
+
retry:
waitfor = 0;
#ifdef USE_SSL
@@ -287,17 +292,16 @@ retry:
/*
* We'll retry the write. Most likely it will return immediately
- * because there's still no data available, and we'll wait for the
- * socket to become ready again.
+ * because there's still no buffer space available, and we'll wait
+ * for the socket to become ready again.
*/
}
goto retry;
}
/*
- * Process interrupts that happened while (or before) sending. Note that
- * we signal that we're not blocking, which will prevent some types of
- * interrupts from being processed.
+ * Process interrupts that happened during a successful (or non-blocking,
+ * or hard-failed) write.
*/
ProcessClientWriteInterrupt(false);