/*
* 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;
}
(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;
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;
* course, only if the interrupt holdoff counter is zero). See the
* related code for details.
*
+ * A lost connection is handled similarly, although the loss of connection
+ * does not raise a signal, but is detected when we fail to write to the
+ * socket. If there was a signal for a broken connection, we could make use of
+ * it by setting ClientConnectionLost in the signal handler.
+ *
* A related, but conceptually distinct, mechanism is the "critical section"
* mechanism. A critical section not only holds off cancel/die interrupts,
* but causes any ereport(ERROR) or ereport(FATAL) to become ereport(PANIC)
extern volatile bool QueryCancelPending;
extern volatile bool ProcDiePending;
+extern volatile bool ClientConnectionLost;
+
/* these are marked volatile because they are examined by signal handlers: */
extern volatile bool ImmediateInterruptOK;
extern PGDLLIMPORT volatile uint32 InterruptHoldoffCount;