Commit cb7ce7d0 authored by Tom Lane's avatar Tom Lane

Fix recent breakage of query-cancel logic, see my pghackers message

of 6 Jan 2001 21:55.
parent 6781aa47
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.198 2000/12/20 21:51:52 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.199 2001/01/07 04:17:29 tgl Exp $
* *
* NOTES * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
...@@ -94,7 +94,7 @@ DLLIMPORT sigjmp_buf Warn_restart; ...@@ -94,7 +94,7 @@ DLLIMPORT sigjmp_buf Warn_restart;
bool Warn_restart_ready = false; bool Warn_restart_ready = false;
bool InError = false; bool InError = false;
bool ProcDiePending = false; volatile bool ProcDiePending = false;
static bool EchoQuery = false; /* default don't echo */ static bool EchoQuery = false; /* default don't echo */
char pg_pathname[MAXPGPATH]; char pg_pathname[MAXPGPATH];
...@@ -920,7 +920,10 @@ finish_xact_command(void) ...@@ -920,7 +920,10 @@ finish_xact_command(void)
void void
handle_warn(SIGNAL_ARGS) handle_warn(SIGNAL_ARGS)
{ {
/* Don't joggle the elbow of a critical section */ /* Don't joggle the elbow of proc_exit */
if (proc_exit_inprogress)
return;
/* Don't joggle the elbow of a critical section, either */
if (CritSectionCount > 0) if (CritSectionCount > 0)
{ {
QueryCancel = true; QueryCancel = true;
...@@ -956,28 +959,38 @@ quickdie(SIGNAL_ARGS) ...@@ -956,28 +959,38 @@ quickdie(SIGNAL_ARGS)
void void
die(SIGNAL_ARGS) die(SIGNAL_ARGS)
{ {
int save_errno = errno;
PG_SETMASK(&BlockSig); PG_SETMASK(&BlockSig);
/* Don't joggle the elbow of a critical section */ /* Don't joggle the elbow of proc_exit */
if (proc_exit_inprogress)
{
errno = save_errno;
return;
}
/* Don't joggle the elbow of a critical section, either */
if (CritSectionCount > 0) if (CritSectionCount > 0)
{ {
QueryCancel = true;
ProcDiePending = true; ProcDiePending = true;
errno = save_errno;
return; return;
} }
/* Don't joggle the elbow of proc_exit, either */ /* Otherwise force immediate proc_exit */
if (proc_exit_inprogress) ForceProcDie();
return;
elog(FATAL, "The system is shutting down");
} }
/* signal handler for floating point exception */ /*
static void * This is split out of die() so that it can be invoked later from
FloatExceptionHandler(SIGNAL_ARGS) * END_CRIT_CODE.
*/
void
ForceProcDie(void)
{ {
elog(ERROR, "floating point exception!" /* Reset flag to avoid another elog() during shutdown */
" The last floating point operation either exceeded legal ranges" ProcDiePending = false;
" or was a divide by zero"); /* Send error message and do proc_exit() */
elog(FATAL, "The system is shutting down");
} }
/* signal handler for query cancel signal from postmaster */ /* signal handler for query cancel signal from postmaster */
...@@ -986,22 +999,41 @@ QueryCancelHandler(SIGNAL_ARGS) ...@@ -986,22 +999,41 @@ QueryCancelHandler(SIGNAL_ARGS)
{ {
int save_errno = errno; int save_errno = errno;
/* Don't joggle the elbow of proc_exit, nor an already-in-progress abort */
if (proc_exit_inprogress || InError)
{
errno = save_errno;
return;
}
/* Set flag to cause CancelQuery to be called when it's safe */
QueryCancel = true; QueryCancel = true;
/* If we happen to be waiting for a lock, get out of that */
LockWaitCancel(); LockWaitCancel();
/* Otherwise, bide our time... */
errno = save_errno; errno = save_errno;
} }
void void
CancelQuery(void) CancelQuery(void)
{ {
/* Reset flag to avoid another elog() during error recovery */
/* QueryCancel = false;
* QueryCancel flag will be reset in main loop, which we reach by /* Create an artificial error condition to get out of query */
* longjmp from elog().
*/
elog(ERROR, "Query was cancelled."); elog(ERROR, "Query was cancelled.");
} }
/* signal handler for floating point exception */
static void
FloatExceptionHandler(SIGNAL_ARGS)
{
elog(ERROR, "floating point exception!"
" The last floating point operation either exceeded legal ranges"
" or was a divide by zero");
}
static void static void
SigHupHandler(SIGNAL_ARGS) SigHupHandler(SIGNAL_ARGS)
{ {
...@@ -1651,7 +1683,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha ...@@ -1651,7 +1683,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
puts("\nPOSTGRES backend interactive interface "); puts("\nPOSTGRES backend interactive interface ");
puts("$Revision: 1.198 $ $Date: 2000/12/20 21:51:52 $\n"); puts("$Revision: 1.199 $ $Date: 2001/01/07 04:17:29 $\n");
} }
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.48 2000/12/28 13:00:24 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.49 2001/01/07 04:17:29 tgl Exp $
* *
* NOTES * NOTES
* Globals used all over the place should be declared here and not * Globals used all over the place should be declared here and not
...@@ -34,7 +34,7 @@ ProtocolVersion FrontendProtocol = PG_PROTOCOL_LATEST; ...@@ -34,7 +34,7 @@ ProtocolVersion FrontendProtocol = PG_PROTOCOL_LATEST;
bool Noversion = false; bool Noversion = false;
bool Quiet = false; bool Quiet = false;
bool QueryCancel = false; volatile bool QueryCancel = false;
int MyProcPid; int MyProcPid;
struct Port *MyProcPort; struct Port *MyProcPort;
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: miscadmin.h,v 1.75 2000/11/29 20:59:54 tgl Exp $ * $Id: miscadmin.h,v 1.76 2001/01/07 04:17:28 tgl Exp $
* *
* NOTES * NOTES
* some of the information in this file will be moved to * some of the information in this file will be moved to
...@@ -42,7 +42,7 @@ extern int PostmasterMain(int argc, char *argv[]); ...@@ -42,7 +42,7 @@ extern int PostmasterMain(int argc, char *argv[]);
*/ */
extern bool Noversion; extern bool Noversion;
extern bool Quiet; extern bool Quiet;
extern bool QueryCancel; extern volatile bool QueryCancel;
extern char *DataDir; extern char *DataDir;
extern int MyProcPid; extern int MyProcPid;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: elog.h,v 1.21 2000/12/18 00:44:50 tgl Exp $ * $Id: elog.h,v 1.22 2001/01/07 04:17:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -30,11 +30,13 @@ extern int Use_syslog; ...@@ -30,11 +30,13 @@ extern int Use_syslog;
/* /*
* If CritSectionCount > 0, signal handlers mustn't do * If CritSectionCount > 0, signal handlers mustn't do
* elog(ERROR|FATAL), instead remember what action is * elog(ERROR|FATAL), instead remember what action is
* required with QueryCancel & ProcDiePending. * required with QueryCancel or ProcDiePending.
* ProcDiePending will be honored at critical section exit,
* but QueryCancel is only checked at specified points.
*/ */
extern uint32 CritSectionCount; /* duplicates access/xlog.h */ extern uint32 CritSectionCount; /* duplicates access/xlog.h */
extern bool QueryCancel; /* duplicates miscadmin.h */ extern volatile bool ProcDiePending;
extern bool ProcDiePending; extern void ForceProcDie(void); /* in postgres.c */
#define START_CRIT_CODE (CritSectionCount++) #define START_CRIT_CODE (CritSectionCount++)
...@@ -43,13 +45,8 @@ extern bool ProcDiePending; ...@@ -43,13 +45,8 @@ extern bool ProcDiePending;
if (CritSectionCount == 0) \ if (CritSectionCount == 0) \
elog(STOP, "Not in critical section"); \ elog(STOP, "Not in critical section"); \
CritSectionCount--; \ CritSectionCount--; \
if (CritSectionCount == 0 && QueryCancel) \ if (CritSectionCount == 0 && ProcDiePending) \
{ \ ForceProcDie(); \
if (ProcDiePending) \
elog(FATAL, "The system is shutting down"); \
else \
elog(ERROR, "Query was cancelled."); \
} \
} while(0) } while(0)
extern bool Log_timestamp; extern bool Log_timestamp;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment