88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.580 2010/01/02 16:57:52 momjian Exp $
11+ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.581 2010/01/07 16:29:58 tgl Exp $
1212 *
1313 * NOTES
1414 * this is the "main" module of the postgres backend and
@@ -476,11 +476,10 @@ prepare_for_client_read(void)
476476 EnableNotifyInterrupt ();
477477 EnableCatchupInterrupt ();
478478
479- /* Allow " die" interrupt to be processed while waiting */
479+ /* Allow cancel/ die interrupts to be processed while waiting */
480480 ImmediateInterruptOK = true;
481481
482482 /* And don't forget to detect one that already arrived */
483- QueryCancelPending = false;
484483 CHECK_FOR_INTERRUPTS ();
485484 }
486485}
@@ -494,7 +493,6 @@ client_read_ended(void)
494493 if (DoingCommandRead )
495494 {
496495 ImmediateInterruptOK = false;
497- QueryCancelPending = false; /* forget any CANCEL signal */
498496
499497 DisableNotifyInterrupt ();
500498 DisableCatchupInterrupt ();
@@ -2640,12 +2638,11 @@ StatementCancelHandler(SIGNAL_ARGS)
26402638 QueryCancelPending = true;
26412639
26422640 /*
2643- * If it's safe to interrupt, and we're waiting for a lock, service
2644- * the interrupt immediately. No point in interrupting if we're
2645- * waiting for input, however.
2641+ * If it's safe to interrupt, and we're waiting for input or a lock,
2642+ * service the interrupt immediately
26462643 */
2647- if (InterruptHoldoffCount == 0 && CritSectionCount == 0 &&
2648- ( DoingCommandRead || ImmediateInterruptOK ) )
2644+ if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
2645+ CritSectionCount == 0 )
26492646 {
26502647 /* bump holdoff count to make ProcessInterrupts() a no-op */
26512648 /* until we are done getting ready for it */
@@ -2717,25 +2714,36 @@ ProcessInterrupts(void)
27172714 if (QueryCancelPending )
27182715 {
27192716 QueryCancelPending = false;
2720- ImmediateInterruptOK = false; /* not idle anymore */
2721- DisableNotifyInterrupt ();
2722- DisableCatchupInterrupt ();
2723- /* As in quickdie, don't risk sending to client during auth */
2724- if (ClientAuthInProgress && whereToSendOutput == DestRemote )
2725- whereToSendOutput = DestNone ;
27262717 if (ClientAuthInProgress )
2718+ {
2719+ ImmediateInterruptOK = false; /* not idle anymore */
2720+ DisableNotifyInterrupt ();
2721+ DisableCatchupInterrupt ();
2722+ /* As in quickdie, don't risk sending to client during auth */
2723+ if (whereToSendOutput == DestRemote )
2724+ whereToSendOutput = DestNone ;
27272725 ereport (ERROR ,
27282726 (errcode (ERRCODE_QUERY_CANCELED ),
27292727 errmsg ("canceling authentication due to timeout" )));
2730- else if (cancel_from_timeout )
2728+ }
2729+ if (cancel_from_timeout )
2730+ {
2731+ ImmediateInterruptOK = false; /* not idle anymore */
2732+ DisableNotifyInterrupt ();
2733+ DisableCatchupInterrupt ();
27312734 ereport (ERROR ,
27322735 (errcode (ERRCODE_QUERY_CANCELED ),
27332736 errmsg ("canceling statement due to statement timeout" )));
2734- else if (IsAutoVacuumWorkerProcess ())
2737+ }
2738+ if (IsAutoVacuumWorkerProcess ())
2739+ {
2740+ ImmediateInterruptOK = false; /* not idle anymore */
2741+ DisableNotifyInterrupt ();
2742+ DisableCatchupInterrupt ();
27352743 ereport (ERROR ,
27362744 (errcode (ERRCODE_QUERY_CANCELED ),
27372745 errmsg ("canceling autovacuum task" )));
2738- else
2746+ }
27392747 {
27402748 int cancelMode = MyProc -> recoveryConflictMode ;
27412749
@@ -2756,34 +2764,50 @@ ProcessInterrupts(void)
27562764 switch (cancelMode )
27572765 {
27582766 case CONFLICT_MODE_FATAL :
2759- Assert (RecoveryInProgress ());
2760- ereport (FATAL ,
2767+ ImmediateInterruptOK = false; /* not idle anymore */
2768+ DisableNotifyInterrupt ();
2769+ DisableCatchupInterrupt ();
2770+ Assert (RecoveryInProgress ());
2771+ ereport (FATAL ,
27612772 (errcode (ERRCODE_QUERY_CANCELED ),
27622773 errmsg ("canceling session due to conflict with recovery" )));
27632774
27642775 case CONFLICT_MODE_ERROR :
2765- /*
2766- * We are aborting because we need to release
2767- * locks. So we need to abort out of all
2768- * subtransactions to make sure we release
2769- * all locks at whatever their level.
2770- *
2771- * XXX Should we try to examine the
2772- * transaction tree and cancel just enough
2773- * subxacts to remove locks? Doubt it.
2774- */
2775- Assert (RecoveryInProgress ());
2776- AbortOutOfAnyTransaction ();
2777- ereport (ERROR ,
2776+ /*
2777+ * We are aborting because we need to release
2778+ * locks. So we need to abort out of all
2779+ * subtransactions to make sure we release
2780+ * all locks at whatever their level.
2781+ *
2782+ * XXX Should we try to examine the
2783+ * transaction tree and cancel just enough
2784+ * subxacts to remove locks? Doubt it.
2785+ */
2786+ ImmediateInterruptOK = false; /* not idle anymore */
2787+ DisableNotifyInterrupt ();
2788+ DisableCatchupInterrupt ();
2789+ Assert (RecoveryInProgress ());
2790+ AbortOutOfAnyTransaction ();
2791+ ereport (ERROR ,
27782792 (errcode (ERRCODE_QUERY_CANCELED ),
27792793 errmsg ("canceling statement due to conflict with recovery" )));
2780- return ;
27812794
27822795 default :
2783- /* No conflict pending, so fall through */
2784- break ;
2796+ /* No conflict pending, so fall through */
2797+ break ;
27852798 }
2799+ }
27862800
2801+ /*
2802+ * If we are reading a command from the client, just ignore the
2803+ * cancel request --- sending an extra error message won't
2804+ * accomplish anything. Otherwise, go ahead and throw the error.
2805+ */
2806+ if (!DoingCommandRead )
2807+ {
2808+ ImmediateInterruptOK = false; /* not idle anymore */
2809+ DisableNotifyInterrupt ();
2810+ DisableCatchupInterrupt ();
27872811 ereport (ERROR ,
27882812 (errcode (ERRCODE_QUERY_CANCELED ),
27892813 errmsg ("canceling statement due to user request" )));
@@ -3626,7 +3650,6 @@ PostgresMain(int argc, char *argv[], const char *username)
36263650 * conditional since we don't want, say, reads on behalf of COPY FROM
36273651 * STDIN doing the same thing.)
36283652 */
3629- QueryCancelPending = false; /* forget any earlier CANCEL signal */
36303653 DoingCommandRead = true;
36313654
36323655 /*
0 commit comments