Fix recent breakage of query-cancel logic, see my pghackers message
of 6 Jan 2001 21:55.
This commit is contained in:
parent
6781aa4707
commit
cb7ce7d0e3
@ -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;
|
|||||||
|
|
||||||
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)
|
|||||||
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,21 +959,72 @@ 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 (CritSectionCount > 0)
|
if (proc_exit_inprogress)
|
||||||
{
|
{
|
||||||
QueryCancel = true;
|
errno = save_errno;
|
||||||
ProcDiePending = true;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Don't joggle the elbow of proc_exit, either */
|
/* Don't joggle the elbow of a critical section, either */
|
||||||
if (proc_exit_inprogress)
|
if (CritSectionCount > 0)
|
||||||
|
{
|
||||||
|
ProcDiePending = true;
|
||||||
|
errno = save_errno;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
/* Otherwise force immediate proc_exit */
|
||||||
|
ForceProcDie();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is split out of die() so that it can be invoked later from
|
||||||
|
* END_CRIT_CODE.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ForceProcDie(void)
|
||||||
|
{
|
||||||
|
/* Reset flag to avoid another elog() during shutdown */
|
||||||
|
ProcDiePending = false;
|
||||||
|
/* Send error message and do proc_exit() */
|
||||||
elog(FATAL, "The system is shutting down");
|
elog(FATAL, "The system is shutting down");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* signal handler for query cancel signal from postmaster */
|
||||||
|
static void
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
/* 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 */
|
/* signal handler for floating point exception */
|
||||||
static void
|
static void
|
||||||
FloatExceptionHandler(SIGNAL_ARGS)
|
FloatExceptionHandler(SIGNAL_ARGS)
|
||||||
@ -980,28 +1034,6 @@ FloatExceptionHandler(SIGNAL_ARGS)
|
|||||||
" or was a divide by zero");
|
" or was a divide by zero");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* signal handler for query cancel signal from postmaster */
|
|
||||||
static void
|
|
||||||
QueryCancelHandler(SIGNAL_ARGS)
|
|
||||||
{
|
|
||||||
int save_errno = errno;
|
|
||||||
|
|
||||||
QueryCancel = true;
|
|
||||||
LockWaitCancel();
|
|
||||||
errno = save_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CancelQuery(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* QueryCancel flag will be reset in main loop, which we reach by
|
|
||||||
* longjmp from elog().
|
|
||||||
*/
|
|
||||||
elog(ERROR, "Query was cancelled.");
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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;
|
|||||||
|
|
||||||
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 @@
|
|||||||
* 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[]);
|
|||||||
*/
|
*/
|
||||||
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 @@
|
|||||||
* 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;
|
|||||||
/*
|
/*
|
||||||
* 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;
|
|||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user