1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-27 22:56:53 +03:00

Code review for statement_timeout patch. Fix some race conditions

between signal handler and enable/disable code, avoid accumulation of
timing error due to trying to maintain remaining-time instead of
absolute-end-time, disable timeout before commit not after.
This commit is contained in:
Tom Lane 2002-10-31 21:34:17 +00:00
parent 8a45a2e9b6
commit 55e4ef138c
6 changed files with 199 additions and 170 deletions

View File

@ -1,4 +1,4 @@
$Header: /cvsroot/pgsql/src/backend/storage/lmgr/README,v 1.11 2002/07/19 00:17:40 momjian Exp $ $Header: /cvsroot/pgsql/src/backend/storage/lmgr/README,v 1.12 2002/10/31 21:34:16 tgl Exp $
LOCKING OVERVIEW LOCKING OVERVIEW
@ -392,7 +392,7 @@ Miscellaneous notes:
asynchronous invocation of deadlock checking. A deadlock cycle in the WFG asynchronous invocation of deadlock checking. A deadlock cycle in the WFG
is formed when the last edge in the cycle is added; therefore the last is formed when the last edge in the cycle is added; therefore the last
process in the cycle to wait (the one from which that edge is outgoing) is process in the cycle to wait (the one from which that edge is outgoing) is
certain to detect and resolve the cycle when it later runs HandleDeadLock. certain to detect and resolve the cycle when it later runs CheckDeadLock.
This holds even if that edge addition created multiple cycles; the process This holds even if that edge addition created multiple cycles; the process
may indeed abort without ever noticing those additional cycles, but we may indeed abort without ever noticing those additional cycles, but we
don't particularly care. The only other possible creation of deadlocks is don't particularly care. The only other possible creation of deadlocks is
@ -402,7 +402,7 @@ it attempts to actually execute any rearrangement.
2. It is not certain that a deadlock will be resolved by aborting the 2. It is not certain that a deadlock will be resolved by aborting the
last-to-wait process. If earlier waiters in the cycle have not yet run last-to-wait process. If earlier waiters in the cycle have not yet run
HandleDeadLock, then the first one to do so will be the victim. CheckDeadLock, then the first one to do so will be the victim.
3. No live (wakable) process can be missed by ProcLockWakeup, since it 3. No live (wakable) process can be missed by ProcLockWakeup, since it
examines every member of the wait queue (this was not true in the 7.0 examines every member of the wait queue (this was not true in the 7.0

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.116 2002/09/26 05:18:30 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.117 2002/10/31 21:34:16 tgl Exp $
* *
* NOTES * NOTES
* Outside modules can create a lock table and acquire/release * Outside modules can create a lock table and acquire/release
@ -882,7 +882,7 @@ WaitOnLock(LOCKMETHOD lockmethod, LOCKMODE lockmode,
/* /*
* NOTE: Think not to put any shared-state cleanup after the call to * NOTE: Think not to put any shared-state cleanup after the call to
* ProcSleep, in either the normal or failure path. The lock state * ProcSleep, in either the normal or failure path. The lock state
* must be fully set by the lock grantor, or by HandleDeadLock if we * must be fully set by the lock grantor, or by CheckDeadLock if we
* give up waiting for the lock. This is necessary because of the * give up waiting for the lock. This is necessary because of the
* possibility that a cancel/die interrupt will interrupt ProcSleep * possibility that a cancel/die interrupt will interrupt ProcSleep
* after someone else grants us the lock, but before we've noticed it. * after someone else grants us the lock, but before we've noticed it.
@ -899,7 +899,7 @@ WaitOnLock(LOCKMETHOD lockmethod, LOCKMODE lockmode,
holder) != STATUS_OK) holder) != STATUS_OK)
{ {
/* /*
* We failed as a result of a deadlock, see HandleDeadLock(). Quit * We failed as a result of a deadlock, see CheckDeadLock(). Quit
* now. Removal of the holder and lock objects, if no longer * now. Removal of the holder and lock objects, if no longer
* needed, will happen in xact cleanup (see above for motivation). * needed, will happen in xact cleanup (see above for motivation).
*/ */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.126 2002/09/25 20:31:40 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.127 2002/10/31 21:34:16 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -52,11 +52,11 @@
#include "storage/sinval.h" #include "storage/sinval.h"
#include "storage/spin.h" #include "storage/spin.h"
/* GUC variables */
int DeadlockTimeout = 1000; int DeadlockTimeout = 1000;
int StatementTimeout = 0; int StatementTimeout = 0;
int RemainingStatementTimeout = 0;
bool alarm_is_statement_timeout = false;
/* Pointer to this process's PGPROC struct, if any */
PGPROC *MyProc = NULL; PGPROC *MyProc = NULL;
/* /*
@ -75,8 +75,16 @@ static PGPROC *DummyProc = NULL;
static bool waitingForLock = false; static bool waitingForLock = false;
static bool waitingForSignal = false; static bool waitingForSignal = false;
/* Mark these volatile because they can be changed by signal handler */
static volatile bool statement_timeout_active = false;
static volatile bool deadlock_timeout_active = false;
/* statement_fin_time is valid only if statement_timeout_active is true */
static struct timeval statement_fin_time;
static void ProcKill(void); static void ProcKill(void);
static void DummyProcKill(void); static void DummyProcKill(void);
static bool CheckStatementTimeout(void);
/* /*
@ -796,14 +804,12 @@ ProcLockWakeup(LOCKMETHODTABLE *lockMethodTable, LOCK *lock)
* and signal an error to ProcSleep. * and signal an error to ProcSleep.
* -------------------- * --------------------
*/ */
void static void
CheckDeadLock(void) CheckDeadLock(void)
{ {
int save_errno = errno;
/* /*
* Acquire locktable lock. Note that the SIGALRM interrupt had better * Acquire locktable lock. Note that the deadlock check interrupt had
* not be enabled anywhere that this process itself holds the * better not be enabled anywhere that this process itself holds the
* locktable lock, else this will wait forever. Also note that * locktable lock, else this will wait forever. Also note that
* LWLockAcquire creates a critical section, so that this routine * LWLockAcquire creates a critical section, so that this routine
* cannot be interrupted by cancel/die interrupts. * cannot be interrupted by cancel/die interrupts.
@ -821,13 +827,11 @@ CheckDeadLock(void)
* This is quicker than checking our semaphore's state, since no * This is quicker than checking our semaphore's state, since no
* kernel call is needed, and it is safe because we hold the locktable * kernel call is needed, and it is safe because we hold the locktable
* lock. * lock.
*
*/ */
if (MyProc->links.prev == INVALID_OFFSET || if (MyProc->links.prev == INVALID_OFFSET ||
MyProc->links.next == INVALID_OFFSET) MyProc->links.next == INVALID_OFFSET)
{ {
LWLockRelease(LockMgrLock); LWLockRelease(LockMgrLock);
errno = save_errno;
return; return;
} }
@ -840,7 +844,6 @@ CheckDeadLock(void)
{ {
/* No deadlock, so keep waiting */ /* No deadlock, so keep waiting */
LWLockRelease(LockMgrLock); LWLockRelease(LockMgrLock);
errno = save_errno;
return; return;
} }
@ -853,7 +856,7 @@ CheckDeadLock(void)
/* /*
* Set MyProc->errType to STATUS_ERROR so that ProcSleep will report * Set MyProc->errType to STATUS_ERROR so that ProcSleep will report
* an error after we return from this signal handler. * an error after we return from the signal handler.
*/ */
MyProc->errType = STATUS_ERROR; MyProc->errType = STATUS_ERROR;
@ -874,7 +877,6 @@ CheckDeadLock(void)
* RemoveFromWaitQueue took care of waking up any such processes. * RemoveFromWaitQueue took care of waking up any such processes.
*/ */
LWLockRelease(LockMgrLock); LWLockRelease(LockMgrLock);
errno = save_errno;
} }
@ -933,188 +935,218 @@ ProcSendSignal(BackendId procId)
* Delay is given in milliseconds. Caller should be sure a SIGALRM * Delay is given in milliseconds. Caller should be sure a SIGALRM
* signal handler is installed before this is called. * signal handler is installed before this is called.
* *
* This code properly handles multiple alarms when the statement_timeout * This code properly handles nesting of deadlock timeout alarms within
* alarm is specified first. * statement timeout alarms.
* *
* Returns TRUE if okay, FALSE on failure. * Returns TRUE if okay, FALSE on failure.
*/ */
bool bool
enable_sig_alarm(int delayms, bool is_statement_timeout) enable_sig_alarm(int delayms, bool is_statement_timeout)
{ {
struct timeval fin_time;
#ifndef __BEOS__ #ifndef __BEOS__
struct itimerval timeval, struct itimerval timeval;
remaining;
#else #else
bigtime_t time_interval, bigtime_t time_interval;
remaining;
#endif #endif
/* /* Compute target timeout time if we will need it */
* Don't set timer if the statement timeout scheduled before next if (is_statement_timeout || statement_timeout_active)
* alarm. {
*/ gettimeofday(&fin_time, NULL);
if (alarm_is_statement_timeout && fin_time.tv_sec += delayms / 1000;
!is_statement_timeout && fin_time.tv_usec += (delayms % 1000) * 1000;
RemainingStatementTimeout <= delayms) if (fin_time.tv_usec >= 1000000)
return true; {
fin_time.tv_sec++;
fin_time.tv_usec -= 1000000;
}
}
if (is_statement_timeout)
{
/* Begin statement-level timeout */
Assert(!deadlock_timeout_active);
statement_fin_time = fin_time;
statement_timeout_active = true;
}
else if (statement_timeout_active)
{
/*
* Begin deadlock timeout with statement-level timeout active
*
* Here, we want to interrupt at the closer of the two timeout
* times. If fin_time >= statement_fin_time then we need not
* touch the existing timer setting; else set up to interrupt
* at the deadlock timeout time.
*
* NOTE: in this case it is possible that this routine will be
* interrupted by the previously-set timer alarm. This is okay
* because the signal handler will do only what it should do according
* to the state variables. The deadlock checker may get run earlier
* than normal, but that does no harm.
*/
deadlock_timeout_active = true;
if (fin_time.tv_sec > statement_fin_time.tv_sec ||
(fin_time.tv_sec == statement_fin_time.tv_sec &&
fin_time.tv_usec >= statement_fin_time.tv_usec))
return true;
}
else
{
/* Begin deadlock timeout with no statement-level timeout */
deadlock_timeout_active = true;
}
/* If we reach here, okay to set the timer interrupt */
#ifndef __BEOS__ #ifndef __BEOS__
MemSet(&timeval, 0, sizeof(struct itimerval)); MemSet(&timeval, 0, sizeof(struct itimerval));
timeval.it_value.tv_sec = delayms / 1000; timeval.it_value.tv_sec = delayms / 1000;
timeval.it_value.tv_usec = (delayms % 1000) * 1000; timeval.it_value.tv_usec = (delayms % 1000) * 1000;
if (setitimer(ITIMER_REAL, &timeval, &remaining)) if (setitimer(ITIMER_REAL, &timeval, NULL))
return false; return false;
#else #else
/* BeOS doesn't have setitimer, but has set_alarm */ /* BeOS doesn't have setitimer, but has set_alarm */
time_interval = delayms * 1000; /* usecs */ time_interval = delayms * 1000; /* usecs */
if ((remaining = set_alarm(time_interval, B_ONE_SHOT_RELATIVE_ALARM)) < 0) if (set_alarm(time_interval, B_ONE_SHOT_RELATIVE_ALARM) < 0)
return false; return false;
#endif #endif
if (is_statement_timeout)
RemainingStatementTimeout = StatementTimeout;
else
{
/* Switching to non-statement-timeout alarm, get remaining time */
if (alarm_is_statement_timeout)
{
#ifndef __BEOS__
/* We lose precision here because we convert to milliseconds */
RemainingStatementTimeout = remaining.it_value.tv_sec * 1000 +
remaining.it_value.tv_usec / 1000;
#else
RemainingStatementTimeout = remaining / 1000;
#endif
/* Rounding could cause a zero */
if (RemainingStatementTimeout == 0)
RemainingStatementTimeout = 1;
}
if (RemainingStatementTimeout)
{
/* Remaining timeout alarm < delayms? */
if (RemainingStatementTimeout <= delayms)
{
/* reinstall statement timeout alarm */
alarm_is_statement_timeout = true;
#ifndef __BEOS__
remaining.it_value.tv_sec = RemainingStatementTimeout / 1000;
remaining.it_value.tv_usec = (RemainingStatementTimeout % 1000) * 1000;
if (setitimer(ITIMER_REAL, &remaining, &timeval))
return false;
else
return true;
#else
remaining = RemainingStatementTimeout * 1000;
if ((timeval = set_alarm(remaining, B_ONE_SHOT_RELATIVE_ALARM)) < 0)
return false;
else
return true;
#endif
}
else
RemainingStatementTimeout -= delayms;
}
}
if (is_statement_timeout)
alarm_is_statement_timeout = true;
else
alarm_is_statement_timeout = false;
return true; return true;
} }
/* /*
* Cancel the SIGALRM timer. * Cancel the SIGALRM timer, either for a deadlock timeout or a statement
* * timeout. If a deadlock timeout is canceled, any active statement timeout
* This is also called if the timer has fired to reschedule * remains in force.
* the statement_timeout timer.
* *
* Returns TRUE if okay, FALSE on failure. * Returns TRUE if okay, FALSE on failure.
*/ */
bool bool
disable_sig_alarm(bool is_statement_timeout) disable_sig_alarm(bool is_statement_timeout)
{ {
/*
* Always disable the interrupt if it is active; this avoids being
* interrupted by the signal handler and thereby possibly getting
* confused.
*
* We will re-enable the interrupt if necessary in CheckStatementTimeout.
*/
if (statement_timeout_active || deadlock_timeout_active)
{
#ifndef __BEOS__ #ifndef __BEOS__
struct itimerval timeval, struct itimerval timeval;
remaining;
MemSet(&timeval, 0, sizeof(struct itimerval)); MemSet(&timeval, 0, sizeof(struct itimerval));
#else if (setitimer(ITIMER_REAL, &timeval, NULL))
bigtime_t time_interval = 0;
#endif
if (!is_statement_timeout && RemainingStatementTimeout)
{ {
#ifndef __BEOS__ statement_timeout_active = deadlock_timeout_active = false;
/* turn off timer and get remaining time, if any */
if (setitimer(ITIMER_REAL, &timeval, &remaining))
return false; return false;
/* Add remaining time back because the timer didn't complete */ }
RemainingStatementTimeout += remaining.it_value.tv_sec * 1000 +
remaining.it_value.tv_usec / 1000;
/* Prepare to set timer */
timeval.it_value.tv_sec = RemainingStatementTimeout / 1000;
timeval.it_value.tv_usec = (RemainingStatementTimeout % 1000) * 1000;
#else #else
/* BeOS doesn't have setitimer, but has set_alarm */ /* BeOS doesn't have setitimer, but has set_alarm */
if ((time_interval = set_alarm(B_INFINITE_TIMEOUT, B_PERIODIC_ALARM)) < 0)
return false;
RemainingStatementTimeout += time_interval / 1000;
time_interval = RemainingStatementTimeout * 1000;
#endif
/* Restore remaining statement timeout value */
alarm_is_statement_timeout = true;
}
/*
* Optimization: is_statement_timeout && RemainingStatementTimeout ==
* 0 does nothing. This is for cases where no timeout was set.
*/
if (!is_statement_timeout || RemainingStatementTimeout)
{
#ifndef __BEOS__
if (setitimer(ITIMER_REAL, &timeval, &remaining))
return false;
#else
if (time_interval)
{
if (set_alarm(time_interval, B_ONE_SHOT_RELATIVE_ALARM) < 0)
return false;
}
else
{
if (set_alarm(B_INFINITE_TIMEOUT, B_PERIODIC_ALARM) < 0) if (set_alarm(B_INFINITE_TIMEOUT, B_PERIODIC_ALARM) < 0)
{
statement_timeout_active = deadlock_timeout_active = false;
return false; return false;
} }
#endif #endif
} }
/* Always cancel deadlock timeout, in case this is error cleanup */
deadlock_timeout_active = false;
/* Cancel or reschedule statement timeout */
if (is_statement_timeout) if (is_statement_timeout)
RemainingStatementTimeout = 0; statement_timeout_active = false;
else if (statement_timeout_active)
{
if (!CheckStatementTimeout())
return false;
}
return true; return true;
} }
/* /*
* Call alarm handler, either StatementCancel or Deadlock checker. * Check for statement timeout. If the timeout time has come,
* trigger a query-cancel interrupt; if not, reschedule the SIGALRM
* interrupt to occur at the right time.
*
* Returns true if okay, false if failed to set the interrupt.
*/ */
void static bool
handle_sig_alarm(SIGNAL_ARGS) CheckStatementTimeout(void)
{ {
if (alarm_is_statement_timeout) struct timeval now;
if (!statement_timeout_active)
return true; /* do nothing if not active */
gettimeofday(&now, NULL);
if (now.tv_sec > statement_fin_time.tv_sec ||
(now.tv_sec == statement_fin_time.tv_sec &&
now.tv_usec >= statement_fin_time.tv_usec))
{ {
RemainingStatementTimeout = 0; /* Time to die */
alarm_is_statement_timeout = false; statement_timeout_active = false;
kill(MyProcPid, SIGINT); kill(MyProcPid, SIGINT);
} }
else else
{ {
CheckDeadLock(); /* Not time yet, so (re)schedule the interrupt */
/* Reactivate any statement_timeout alarm. */ #ifndef __BEOS__
disable_sig_alarm(false); struct itimerval timeval;
MemSet(&timeval, 0, sizeof(struct itimerval));
timeval.it_value.tv_sec = statement_fin_time.tv_sec - now.tv_sec;
timeval.it_value.tv_usec = statement_fin_time.tv_usec - now.tv_usec;
if (timeval.it_value.tv_usec < 0)
{
timeval.it_value.tv_sec--;
timeval.it_value.tv_usec += 1000000;
} }
if (setitimer(ITIMER_REAL, &timeval, NULL))
return false;
#else
/* BeOS doesn't have setitimer, but has set_alarm */
bigtime_t time_interval;
time_interval =
(statement_fin_time.tv_sec - now.tv_sec) * 1000000 +
(statement_fin_time.tv_usec - now.tv_usec);
if (set_alarm(time_interval, B_ONE_SHOT_RELATIVE_ALARM) < 0)
return false;
#endif
}
return true;
}
/*
* Signal handler for SIGALRM
*
* Process deadlock check and/or statement timeout check, as needed.
* To avoid various edge cases, we must be careful to do nothing
* when there is nothing to be done. We also need to be able to
* reschedule the timer interrupt if called before end of statement.
*/
void
handle_sig_alarm(SIGNAL_ARGS)
{
int save_errno = errno;
if (deadlock_timeout_active)
{
deadlock_timeout_active = false;
CheckDeadLock();
}
if (statement_timeout_active)
(void) CheckStatementTimeout();
errno = save_errno;
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.306 2002/10/24 23:19:13 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.307 2002/10/31 21:34:16 tgl Exp $
* *
* NOTES * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
@ -75,8 +75,6 @@ char *debug_query_string; /* for pgmonitor and
/* Note: whereToSendOutput is initialized for the bootstrap/standalone case */ /* Note: whereToSendOutput is initialized for the bootstrap/standalone case */
CommandDest whereToSendOutput = Debug; CommandDest whereToSendOutput = Debug;
extern int StatementTimeout;
static bool dontExecute = false; static bool dontExecute = false;
/* note: these declarations had better match tcopprot.h */ /* note: these declarations had better match tcopprot.h */
@ -582,9 +580,6 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */
start_xact_command(); start_xact_command();
xact_started = true; xact_started = true;
if (StatementTimeout)
enable_sig_alarm(StatementTimeout, true);
/* /*
* parse_context *must* be different from the execution memory * parse_context *must* be different from the execution memory
* context, else the context reset at the bottom of the loop will * context, else the context reset at the bottom of the loop will
@ -931,8 +926,6 @@ pg_exec_query_string(StringInfo query_string, /* string to execute */
EndCommand(commandTag, dest); EndCommand(commandTag, dest);
} /* end loop over parsetrees */ } /* end loop over parsetrees */
disable_sig_alarm(true);
/* /*
* Close down transaction statement, if one is open. (Note that this * Close down transaction statement, if one is open. (Note that this
* will only happen if the querystring was empty.) * will only happen if the querystring was empty.)
@ -964,6 +957,10 @@ start_xact_command(void)
{ {
elog(DEBUG1, "StartTransactionCommand"); elog(DEBUG1, "StartTransactionCommand");
StartTransactionCommand(false); StartTransactionCommand(false);
/* Set statement timeout running, if any */
if (StatementTimeout > 0)
enable_sig_alarm(StatementTimeout, true);
} }
static void static void
@ -972,6 +969,9 @@ finish_xact_command(bool forceCommit)
/* Invoke IMMEDIATE constraint triggers */ /* Invoke IMMEDIATE constraint triggers */
DeferredTriggerEndQuery(); DeferredTriggerEndQuery();
/* Cancel any active statement timeout before committing */
disable_sig_alarm(true);
/* Now commit the command */ /* Now commit the command */
elog(DEBUG1, "CommitTransactionCommand"); elog(DEBUG1, "CommitTransactionCommand");
@ -1047,7 +1047,7 @@ die(SIGNAL_ARGS)
/* until we are done getting ready for it */ /* until we are done getting ready for it */
InterruptHoldoffCount++; InterruptHoldoffCount++;
DisableNotifyInterrupt(); DisableNotifyInterrupt();
/* Make sure HandleDeadLock won't run while shutting down... */ /* Make sure CheckDeadLock won't run while shutting down... */
LockWaitCancel(); LockWaitCancel();
InterruptHoldoffCount--; InterruptHoldoffCount--;
ProcessInterrupts(); ProcessInterrupts();
@ -1648,8 +1648,7 @@ PostgresMain(int argc, char *argv[], const char *username)
pqsignal(SIGINT, StatementCancelHandler); /* cancel current query */ pqsignal(SIGINT, StatementCancelHandler); /* cancel current query */
pqsignal(SIGTERM, die); /* cancel current query and exit */ pqsignal(SIGTERM, die); /* cancel current query and exit */
pqsignal(SIGQUIT, quickdie); /* hard crash time */ pqsignal(SIGQUIT, quickdie); /* hard crash time */
pqsignal(SIGALRM, handle_sig_alarm); /* check for deadlock pqsignal(SIGALRM, handle_sig_alarm); /* timeout conditions */
* after timeout */
/* /*
* Ignore failure to write to frontend. Note: if frontend closes * Ignore failure to write to frontend. Note: if frontend closes
@ -1782,7 +1781,7 @@ PostgresMain(int argc, char *argv[], const char *username)
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
puts("\nPOSTGRES backend interactive interface "); puts("\nPOSTGRES backend interactive interface ");
puts("$Revision: 1.306 $ $Date: 2002/10/24 23:19:13 $\n"); puts("$Revision: 1.307 $ $Date: 2002/10/31 21:34:16 $\n");
} }
/* /*
@ -1829,6 +1828,8 @@ PostgresMain(int argc, char *argv[], const char *username)
QueryCancelPending = false; QueryCancelPending = false;
InterruptHoldoffCount = 1; InterruptHoldoffCount = 1;
CritSectionCount = 0; /* should be unnecessary, but... */ CritSectionCount = 0; /* should be unnecessary, but... */
disable_sig_alarm(true);
QueryCancelPending = false; /* again in case timeout occurred */
DisableNotifyInterrupt(); DisableNotifyInterrupt();
debug_query_string = NULL; debug_query_string = NULL;
@ -1915,9 +1916,6 @@ PostgresMain(int argc, char *argv[], const char *username)
QueryCancelPending = false; /* forget any earlier CANCEL QueryCancelPending = false; /* forget any earlier CANCEL
* signal */ * signal */
/* Stop any statement timer */
disable_sig_alarm(true);
EnableNotifyInterrupt(); EnableNotifyInterrupt();
/* Allow "die" interrupt to be processed while waiting */ /* Allow "die" interrupt to be processed while waiting */

View File

@ -5,7 +5,7 @@
* command, configuration file, and command line options. * command, configuration file, and command line options.
* See src/backend/utils/misc/README for more information. * See src/backend/utils/misc/README for more information.
* *
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.97 2002/10/02 16:27:57 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.98 2002/10/31 21:34:17 tgl Exp $
* *
* Copyright 2000 by PostgreSQL Global Development Group * Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
@ -56,7 +56,6 @@
extern bool Log_connections; extern bool Log_connections;
extern int PreAuthDelay; extern int PreAuthDelay;
extern int AuthenticationTimeout; extern int AuthenticationTimeout;
extern int StatementTimeout;
extern int CheckPointTimeout; extern int CheckPointTimeout;
extern bool autocommit; extern bool autocommit;
extern int CommitDelay; extern int CommitDelay;

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: proc.h,v 1.61 2002/10/21 18:57:34 petere Exp $ * $Id: proc.h,v 1.62 2002/10/31 21:34:17 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -86,8 +86,9 @@ typedef struct PROC_HDR
} PROC_HDR; } PROC_HDR;
/* configurable option */ /* configurable options */
extern int DeadlockTimeout; extern int DeadlockTimeout;
extern int StatementTimeout;
/* /*
@ -105,7 +106,6 @@ extern int ProcSleep(LOCKMETHODTABLE *lockMethodTable, LOCKMODE lockmode,
extern PGPROC *ProcWakeup(PGPROC *proc, int errType); extern PGPROC *ProcWakeup(PGPROC *proc, int errType);
extern void ProcLockWakeup(LOCKMETHODTABLE *lockMethodTable, LOCK *lock); extern void ProcLockWakeup(LOCKMETHODTABLE *lockMethodTable, LOCK *lock);
extern bool LockWaitCancel(void); extern bool LockWaitCancel(void);
extern void CheckDeadLock(void);
extern void ProcWaitForSignal(void); extern void ProcWaitForSignal(void);
extern void ProcCancelWaitForSignal(void); extern void ProcCancelWaitForSignal(void);