summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/tcop/postgres.c74
-rw-r--r--src/backend/utils/init/globals.c4
-rw-r--r--src/include/miscadmin.h4
-rw-r--r--src/include/utils/elog.h19
4 files changed, 65 insertions, 36 deletions
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index a8b7b4ec1bc..a73ba4df4ab 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
*
*
* 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
* this is the "main" module of the postgres backend and
@@ -94,7 +94,7 @@ DLLIMPORT sigjmp_buf Warn_restart;
bool Warn_restart_ready = false;
bool InError = false;
-bool ProcDiePending = false;
+volatile bool ProcDiePending = false;
static bool EchoQuery = false; /* default don't echo */
char pg_pathname[MAXPGPATH];
@@ -920,7 +920,10 @@ finish_xact_command(void)
void
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)
{
QueryCancel = true;
@@ -956,28 +959,38 @@ quickdie(SIGNAL_ARGS)
void
die(SIGNAL_ARGS)
{
+ int save_errno = errno;
+
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)
{
- QueryCancel = true;
ProcDiePending = true;
+ errno = save_errno;
return;
}
- /* Don't joggle the elbow of proc_exit, either */
- if (proc_exit_inprogress)
- return;
- elog(FATAL, "The system is shutting down");
+ /* Otherwise force immediate proc_exit */
+ ForceProcDie();
}
-/* signal handler for floating point exception */
-static void
-FloatExceptionHandler(SIGNAL_ARGS)
+/*
+ * This is split out of die() so that it can be invoked later from
+ * END_CRIT_CODE.
+ */
+void
+ForceProcDie(void)
{
- elog(ERROR, "floating point exception!"
- " The last floating point operation either exceeded legal ranges"
- " or was a divide by zero");
+ /* Reset flag to avoid another elog() during shutdown */
+ ProcDiePending = false;
+ /* Send error message and do proc_exit() */
+ elog(FATAL, "The system is shutting down");
}
/* signal handler for query cancel signal from postmaster */
@@ -986,22 +999,41 @@ QueryCancelHandler(SIGNAL_ARGS)
{
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;
+
+ /* If we happen to be waiting for a lock, get out of that */
LockWaitCancel();
+
+ /* Otherwise, bide our time... */
errno = save_errno;
}
void
CancelQuery(void)
{
-
- /*
- * QueryCancel flag will be reset in main loop, which we reach by
- * longjmp from elog().
- */
+ /* Reset flag to avoid another elog() during error recovery */
+ QueryCancel = false;
+ /* Create an artificial error condition to get out of query */
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
SigHupHandler(SIGNAL_ARGS)
{
@@ -1651,7 +1683,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
if (!IsUnderPostmaster)
{
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");
}
/*
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
index e6b57c648b3..4359ef60a88 100644
--- a/src/backend/utils/init/globals.c
+++ b/src/backend/utils/init/globals.c
@@ -8,7 +8,7 @@
*
*
* 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
* Globals used all over the place should be declared here and not
@@ -34,7 +34,7 @@ ProtocolVersion FrontendProtocol = PG_PROTOCOL_LATEST;
bool Noversion = false;
bool Quiet = false;
-bool QueryCancel = false;
+volatile bool QueryCancel = false;
int MyProcPid;
struct Port *MyProcPort;
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index f41a01822ac..6b5dff9478a 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* 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
* some of the information in this file will be moved to
@@ -42,7 +42,7 @@ extern int PostmasterMain(int argc, char *argv[]);
*/
extern bool Noversion;
extern bool Quiet;
-extern bool QueryCancel;
+extern volatile bool QueryCancel;
extern char *DataDir;
extern int MyProcPid;
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index 37db2c7aaf8..e7305d67fc2 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* 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;
/*
* If CritSectionCount > 0, signal handlers mustn't do
* 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 bool QueryCancel; /* duplicates miscadmin.h */
-extern bool ProcDiePending;
+extern volatile bool ProcDiePending;
+extern void ForceProcDie(void); /* in postgres.c */
#define START_CRIT_CODE (CritSectionCount++)
@@ -43,13 +45,8 @@ extern bool ProcDiePending;
if (CritSectionCount == 0) \
elog(STOP, "Not in critical section"); \
CritSectionCount--; \
- if (CritSectionCount == 0 && QueryCancel) \
- { \
- if (ProcDiePending) \
- elog(FATAL, "The system is shutting down"); \
- else \
- elog(ERROR, "Query was cancelled."); \
- } \
+ if (CritSectionCount == 0 && ProcDiePending) \
+ ForceProcDie(); \
} while(0)
extern bool Log_timestamp;