mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
Fix a problem in my recent patch to initialize cancel_key for autovac workers
as well as regular backends: if no regular backend launches before the autovac launcher tries to start an autovac worker, the postmaster would get an Assert fault due to calling PostmasterRandom before random_seed was initialized. Cleanest solution seems to be to take the initialization of random_seed out of ServerLoop and let PostmasterRandom do it for itself.
This commit is contained in:
parent
bdd6b62245
commit
0b9d3d4dcd
@ -37,7 +37,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.538 2007/08/03 20:06:50 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.539 2007/08/04 03:15:49 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
*
|
||||
@ -230,6 +230,7 @@ static volatile sig_atomic_t start_autovac_launcher = false;
|
||||
* backend from the postmaster to that backend (via fork).
|
||||
*/
|
||||
static unsigned int random_seed = 0;
|
||||
static struct timeval random_start_time;
|
||||
|
||||
extern char *optarg;
|
||||
extern int optind,
|
||||
@ -966,6 +967,8 @@ PostmasterMain(int argc, char *argv[])
|
||||
* Remember postmaster startup time
|
||||
*/
|
||||
PgStartTime = GetCurrentTimestamp();
|
||||
/* PostmasterRandom wants its own copy */
|
||||
gettimeofday(&random_start_time, NULL);
|
||||
|
||||
/*
|
||||
* We're ready to rock and roll...
|
||||
@ -1140,10 +1143,7 @@ ServerLoop(void)
|
||||
int nSockets;
|
||||
time_t now,
|
||||
last_touch_time;
|
||||
struct timeval earlier,
|
||||
later;
|
||||
|
||||
gettimeofday(&earlier, NULL);
|
||||
last_touch_time = time(NULL);
|
||||
|
||||
nSockets = initMasks(&readmask);
|
||||
@ -1194,24 +1194,6 @@ ServerLoop(void)
|
||||
*/
|
||||
if (selres > 0)
|
||||
{
|
||||
/*
|
||||
* Select a random seed at the time of first receiving a request.
|
||||
*/
|
||||
while (random_seed == 0)
|
||||
{
|
||||
gettimeofday(&later, NULL);
|
||||
|
||||
/*
|
||||
* We are not sure how much precision is in tv_usec, so we
|
||||
* swap the high and low 16 bits of 'later' and XOR them with
|
||||
* 'earlier'. On the off chance that the result is 0, we loop
|
||||
* until it isn't.
|
||||
*/
|
||||
random_seed = earlier.tv_usec ^
|
||||
((later.tv_usec << 16) |
|
||||
((later.tv_usec >> 16) & 0xffff));
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXLISTEN; i++)
|
||||
{
|
||||
if (ListenSocket[i] == -1)
|
||||
@ -2970,6 +2952,7 @@ BackendRun(Port *port)
|
||||
* a new random sequence in the random() library function.
|
||||
*/
|
||||
random_seed = 0;
|
||||
random_start_time.tv_usec = 0;
|
||||
/* slightly hacky way to get integer microseconds part of timestamptz */
|
||||
TimestampDifference(0, port->SessionStartTime, &secs, &usecs);
|
||||
srandom((unsigned int) (MyProcPid ^ usecs));
|
||||
@ -3778,13 +3761,29 @@ RandomSalt(char *cryptSalt, char *md5Salt)
|
||||
static long
|
||||
PostmasterRandom(void)
|
||||
{
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized)
|
||||
/*
|
||||
* Select a random seed at the time of first receiving a request.
|
||||
*/
|
||||
if (random_seed == 0)
|
||||
{
|
||||
Assert(random_seed != 0);
|
||||
do
|
||||
{
|
||||
struct timeval random_stop_time;
|
||||
|
||||
gettimeofday(&random_stop_time, NULL);
|
||||
/*
|
||||
* We are not sure how much precision is in tv_usec, so we swap
|
||||
* the high and low 16 bits of 'random_stop_time' and XOR them
|
||||
* with 'random_start_time'. On the off chance that the result is
|
||||
* 0, we loop until it isn't.
|
||||
*/
|
||||
random_seed = random_start_time.tv_usec ^
|
||||
((random_stop_time.tv_usec << 16) |
|
||||
((random_stop_time.tv_usec >> 16) & 0xffff));
|
||||
}
|
||||
while (random_seed == 0);
|
||||
|
||||
srandom(random_seed);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return random();
|
||||
|
Loading…
Reference in New Issue
Block a user