summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorHeikki Linnakangas2011-12-09 09:37:21 +0000
committerHeikki Linnakangas2011-12-09 12:21:36 +0000
commit5d8a894e3095b2f602e901c19689f3176bf20543 (patch)
treeb917c7012c64edb02883ac4e3a2ed59368cbc06e /src/backend
parentd5f23af6bfbc454e86dd16e5c7a0bfc0cf6189d0 (diff)
Cancel running query if it is detected that the connection to the client is
lost. The only way we detect that at the moment is when write() fails when we try to write to the socket. Florian Pflug with small changes by me, reviewed by Greg Jaskiewicz.
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/libpq/pqcomm.c6
-rw-r--r--src/backend/tcop/postgres.c12
-rw-r--r--src/backend/utils/init/globals.c1
3 files changed, 18 insertions, 1 deletions
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index b83a2efb698..c36cf318267 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1247,9 +1247,13 @@ internal_flush(void)
/*
* We drop the buffered data anyway so that processing can
- * continue, even though we'll probably quit soon.
+ * continue, even though we'll probably quit soon. We also
+ * set a flag that'll cause the next CHECK_FOR_INTERRUPTS
+ * to terminate the connection.
*/
PqSendStart = PqSendPointer = 0;
+ ClientConnectionLost = 1;
+ InterruptPending = 1;
return EOF;
}
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 976a832135e..5bb16e010cc 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -2823,6 +2823,18 @@ ProcessInterrupts(void)
(errcode(ERRCODE_ADMIN_SHUTDOWN),
errmsg("terminating connection due to administrator command")));
}
+ if (ClientConnectionLost)
+ {
+ QueryCancelPending = false; /* lost connection trumps QueryCancel */
+ ImmediateInterruptOK = false; /* not idle anymore */
+ DisableNotifyInterrupt();
+ DisableCatchupInterrupt();
+ /* don't send to client, we already know the connection to be dead. */
+ whereToSendOutput = DestNone;
+ ereport(FATAL,
+ (errcode(ERRCODE_CONNECTION_FAILURE),
+ errmsg("connection to client lost")));
+ }
if (QueryCancelPending)
{
QueryCancelPending = false;
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
index 9ce64e67629..9417c7a3b04 100644
--- a/src/backend/utils/init/globals.c
+++ b/src/backend/utils/init/globals.c
@@ -29,6 +29,7 @@ ProtocolVersion FrontendProtocol;
volatile bool InterruptPending = false;
volatile bool QueryCancelPending = false;
volatile bool ProcDiePending = false;
+volatile bool ClientConnectionLost = false;
volatile bool ImmediateInterruptOK = false;
volatile uint32 InterruptHoldoffCount = 0;
volatile uint32 CritSectionCount = 0;