diff options
Diffstat (limited to 'src/backend/tcop/postgres.c')
-rw-r--r-- | src/backend/tcop/postgres.c | 50 |
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). |