OSDN Git Service

Fix recent breakage of query-cancel logic, see my pghackers message
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 7 Jan 2001 04:17:29 +0000 (04:17 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 7 Jan 2001 04:17:29 +0000 (04:17 +0000)
of 6 Jan 2001 21:55.

src/backend/tcop/postgres.c
src/backend/utils/init/globals.c
src/include/miscadmin.h
src/include/utils/elog.h

index a8b7b4e..a73ba4d 100644 (file)
@@ -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");
        }
 
        /*
index e6b57c6..4359ef6 100644 (file)
@@ -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;
index f41a018..6b5dff9 100644 (file)
@@ -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;
index 37db2c7..e7305d6 100644 (file)
@@ -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;