OSDN Git Service

Fix for rare race-condition-like failure: if a backend receives SIGUSR2
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 16 Sep 2002 01:24:41 +0000 (01:24 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 16 Sep 2002 01:24:41 +0000 (01:24 +0000)
(notify/SI-overrun interrupt) while it is in process of doing proc_exit,
it is possible for Async_NotifyHandler() to try to start a transaction
when one is already running.  This leads to Asserts() or worse.  I think
it may only be possible to occur when frontend synchronization is lost
(ie, the elog(FATAL) in SocketBackend() fires), but that is a standard
occurrence after error during COPY.  In any case, I have seen this
failure occur during regression tests, so it is definitely possible.

src/backend/commands/async.c
src/backend/tcop/postgres.c

index 1945c75..a3c27b8 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.90 2002/09/02 02:47:01 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.91 2002/09/16 01:24:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -593,6 +593,10 @@ Async_NotifyHandler(SIGNAL_ARGS)
         * ever turned on.
         */
 
+       /* Don't joggle the elbow of proc_exit */
+       if (proc_exit_inprogress)
+               return;
+
        if (notifyInterruptEnabled)
        {
                /*
index 01d8100..cd5f765 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.291 2002/09/04 20:31:26 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.292 2002/09/16 01:24:41 tgl Exp $
  *
  * NOTES
  *       this is the "main" module of the postgres backend and
@@ -1071,12 +1071,14 @@ ProcessInterrupts(void)
                ProcDiePending = false;
                QueryCancelPending = false;             /* ProcDie trumps QueryCancel */
                ImmediateInterruptOK = false;   /* not idle anymore */
+               DisableNotifyInterrupt();
                elog(FATAL, "This connection has been terminated by the administrator.");
        }
        if (QueryCancelPending)
        {
                QueryCancelPending = false;
                ImmediateInterruptOK = false;   /* not idle anymore */
+               DisableNotifyInterrupt();
                elog(ERROR, "Query was cancelled.");
        }
        /* If we get here, do nothing (probably, QueryCancelPending was reset) */
@@ -1689,7 +1691,7 @@ PostgresMain(int argc, char *argv[], const char *username)
        if (!IsUnderPostmaster)
        {
                puts("\nPOSTGRES backend interactive interface ");
-               puts("$Revision: 1.291 $ $Date: 2002/09/04 20:31:26 $\n");
+               puts("$Revision: 1.292 $ $Date: 2002/09/16 01:24:41 $\n");
        }
 
        /*
@@ -1736,6 +1738,7 @@ PostgresMain(int argc, char *argv[], const char *username)
                QueryCancelPending = false;
                InterruptHoldoffCount = 1;
                CritSectionCount = 0;   /* should be unnecessary, but... */
+               DisableNotifyInterrupt();
                debug_query_string = NULL;
 
                /*