mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
Use WaitLatch, not pg_usleep, for delaying in pg_sleep().
This avoids platform-dependent behavior wherein pg_sleep() might fail to be interrupted by statement timeout, query cancel, SIGTERM, etc. Also, since there's no reason to wake up once a second any more, we can reduce the power consumption of a sleeping backend a tad. Back-patch to 9.3, since use of SA_RESTART for SIGALRM makes this a bigger issue than it used to be.
This commit is contained in:
parent
f69aece6f4
commit
a64ca63e59
@ -384,16 +384,16 @@ pg_sleep(PG_FUNCTION_ARGS)
|
|||||||
float8 endtime;
|
float8 endtime;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We break the requested sleep into segments of no more than 1 second, to
|
* We sleep using WaitLatch, to ensure that we'll wake up promptly if an
|
||||||
* put an upper bound on how long it will take us to respond to a cancel
|
* important signal (such as SIGALRM or SIGINT) arrives. Because
|
||||||
* or die interrupt. (Note that pg_usleep is interruptible by signals on
|
* WaitLatch's upper limit of delay is INT_MAX milliseconds, and the user
|
||||||
* some platforms but not others.) Also, this method avoids exposing
|
* might ask for more than that, we sleep for at most 10 minutes and then
|
||||||
* pg_usleep's upper bound on allowed delays.
|
* loop.
|
||||||
*
|
*
|
||||||
* By computing the intended stop time initially, we avoid accumulation of
|
* By computing the intended stop time initially, we avoid accumulation of
|
||||||
* extra delay across multiple sleeps. This also ensures we won't delay
|
* extra delay across multiple sleeps. This also ensures we won't delay
|
||||||
* less than the specified time if pg_usleep is interrupted by other
|
* less than the specified time when WaitLatch is terminated early by a
|
||||||
* signals such as SIGHUP.
|
* non-query-cancelling signal such as SIGHUP.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_INT64_TIMESTAMP
|
#ifdef HAVE_INT64_TIMESTAMP
|
||||||
@ -407,15 +407,22 @@ pg_sleep(PG_FUNCTION_ARGS)
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
float8 delay;
|
float8 delay;
|
||||||
|
long delay_ms;
|
||||||
|
|
||||||
CHECK_FOR_INTERRUPTS();
|
CHECK_FOR_INTERRUPTS();
|
||||||
|
|
||||||
delay = endtime - GetNowFloat();
|
delay = endtime - GetNowFloat();
|
||||||
if (delay >= 1.0)
|
if (delay >= 600.0)
|
||||||
pg_usleep(1000000L);
|
delay_ms = 600000;
|
||||||
else if (delay > 0.0)
|
else if (delay > 0.0)
|
||||||
pg_usleep((long) ceil(delay * 1000000.0));
|
delay_ms = (long) ceil(delay * 1000.0);
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
(void) WaitLatch(&MyProc->procLatch,
|
||||||
|
WL_LATCH_SET | WL_TIMEOUT,
|
||||||
|
delay_ms);
|
||||||
|
ResetLatch(&MyProc->procLatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user