aboutsummaryrefslogtreecommitdiff
path: root/src/backend/tcop/postgres.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/tcop/postgres.c')
-rw-r--r--src/backend/tcop/postgres.c50
1 files changed, 48 insertions, 2 deletions
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index bcc4f243134..7e9408e61d9 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -318,7 +318,7 @@ interactive_getc(void)
c = getc(stdin);
- ProcessClientReadInterrupt();
+ ProcessClientReadInterrupt(true);
return c;
}
@@ -529,7 +529,7 @@ ReadCommand(StringInfo inBuf)
* Must preserve errno!
*/
void
-ProcessClientReadInterrupt(void)
+ProcessClientReadInterrupt(bool blocked)
{
int save_errno = errno;
@@ -546,10 +546,56 @@ ProcessClientReadInterrupt(void)
if (notifyInterruptPending)
ProcessNotifyInterrupt();
}
+ else if (ProcDiePending && blocked)
+ {
+ /*
+ * We're dying. It's safe (and sane) to handle that now.
+ */
+ CHECK_FOR_INTERRUPTS();
+ }
errno = save_errno;
}
+/*
+ * ProcessClientWriteInterrupt() - Process interrupts specific to client writes
+ *
+ * This is called just after low-level writes. That might be after the read
+ * finished successfully, or it was interrupted via interrupt. 'blocked' tells
+ * us whether the
+ *
+ * Must preserve errno!
+ */
+void
+ProcessClientWriteInterrupt(bool blocked)
+{
+ int save_errno = errno;
+
+ Assert(InterruptHoldoffCount == 0 && CritSectionCount == 0);
+
+ /*
+ * We only want to process the interrupt here if socket writes are
+ * blocking to increase the chance to get an error message to the
+ * client. If we're not blocked there'll soon be a
+ * CHECK_FOR_INTERRUPTS(). But if we're blocked we'll never get out of
+ * that situation if the client has died.
+ */
+ if (ProcDiePending && blocked)
+ {
+ /*
+ * We're dying. It's safe (and sane) to handle that now. But we don't
+ * want to send the client the error message as that a) would possibly
+ * block again b) would possibly lead to sending an error message to
+ * the client, while we already started to send something else.
+ */
+ if (whereToSendOutput == DestRemote)
+ whereToSendOutput = DestNone;
+
+ CHECK_FOR_INTERRUPTS();
+ }
+
+ errno = save_errno;
+}
/*
* Do raw parsing (only).