Use nanosleep(2) in pg_usleep, if available?
Tom Lane <tgl@sss.pgh.pa.us>
From: Tom Lane <tgl@sss.pgh.pa.us>
To: pgsql-hackers@lists.postgresql.org
Date: 2019-03-12T00:03:40Z
Lists: pgsql-hackers
In the thread about vacuum_cost_delay vs vacuum_cost_limit, I wondered whether nanosleep(2) would provide any better timing resolution than select(2). Some experimentation suggests that it doesn't, but nonetheless I see a good reason why we should consider making pg_usleep use nanosleep() if possible: it's got much better-defined semantics for what happens if a signal arrives. The comments for pg_usleep lay out the problems with relying on select(): * CAUTION: the behavior when a signal arrives during the sleep is platform * dependent. On most Unix-ish platforms, a signal does not terminate the * sleep; but on some, it will (the Windows implementation also allows signals * to terminate pg_usleep). And there are platforms where not only does a * signal not terminate the sleep, but it actually resets the timeout counter * so that the sleep effectively starts over! It is therefore rather hazardous * to use this for long sleeps; a continuing stream of signal events could * prevent the sleep from ever terminating. Better practice for long sleeps * is to use WaitLatch() with a timeout. While the WaitLatch alternative avoids the problem, I doubt we're ever going to remove pg_usleep entirely, so it'd be good if it had fewer sharp edges. nanosleep() has the same behavior as Windows, ie, the sleep is guaranteed to be terminated by a signal. So if we used nanosleep() where available we'd have that behavior on just about every interesting platform. nanosleep() does exist pretty far back: it's in SUSv2, though that version of the standard allows it to fail with ENOSYS. Not sure if we'd need to teach configure to check for that possibility. Thoughts? regards, tom lane
Commits
-
Use nanosleep() to implement pg_usleep().
- a948e49e2ef1 16.0 landed