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
|
* 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
|
* NOTES
|
||||||
*
|
*
|
||||||
@ -230,6 +230,7 @@ static volatile sig_atomic_t start_autovac_launcher = false;
|
|||||||
* backend from the postmaster to that backend (via fork).
|
* backend from the postmaster to that backend (via fork).
|
||||||
*/
|
*/
|
||||||
static unsigned int random_seed = 0;
|
static unsigned int random_seed = 0;
|
||||||
|
static struct timeval random_start_time;
|
||||||
|
|
||||||
extern char *optarg;
|
extern char *optarg;
|
||||||
extern int optind,
|
extern int optind,
|
||||||
@ -966,6 +967,8 @@ PostmasterMain(int argc, char *argv[])
|
|||||||
* Remember postmaster startup time
|
* Remember postmaster startup time
|
||||||
*/
|
*/
|
||||||
PgStartTime = GetCurrentTimestamp();
|
PgStartTime = GetCurrentTimestamp();
|
||||||
|
/* PostmasterRandom wants its own copy */
|
||||||
|
gettimeofday(&random_start_time, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We're ready to rock and roll...
|
* We're ready to rock and roll...
|
||||||
@ -1140,10 +1143,7 @@ ServerLoop(void)
|
|||||||
int nSockets;
|
int nSockets;
|
||||||
time_t now,
|
time_t now,
|
||||||
last_touch_time;
|
last_touch_time;
|
||||||
struct timeval earlier,
|
|
||||||
later;
|
|
||||||
|
|
||||||
gettimeofday(&earlier, NULL);
|
|
||||||
last_touch_time = time(NULL);
|
last_touch_time = time(NULL);
|
||||||
|
|
||||||
nSockets = initMasks(&readmask);
|
nSockets = initMasks(&readmask);
|
||||||
@ -1194,24 +1194,6 @@ ServerLoop(void)
|
|||||||
*/
|
*/
|
||||||
if (selres > 0)
|
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++)
|
for (i = 0; i < MAXLISTEN; i++)
|
||||||
{
|
{
|
||||||
if (ListenSocket[i] == -1)
|
if (ListenSocket[i] == -1)
|
||||||
@ -2970,6 +2952,7 @@ BackendRun(Port *port)
|
|||||||
* a new random sequence in the random() library function.
|
* a new random sequence in the random() library function.
|
||||||
*/
|
*/
|
||||||
random_seed = 0;
|
random_seed = 0;
|
||||||
|
random_start_time.tv_usec = 0;
|
||||||
/* slightly hacky way to get integer microseconds part of timestamptz */
|
/* slightly hacky way to get integer microseconds part of timestamptz */
|
||||||
TimestampDifference(0, port->SessionStartTime, &secs, &usecs);
|
TimestampDifference(0, port->SessionStartTime, &secs, &usecs);
|
||||||
srandom((unsigned int) (MyProcPid ^ usecs));
|
srandom((unsigned int) (MyProcPid ^ usecs));
|
||||||
@ -3778,13 +3761,29 @@ RandomSalt(char *cryptSalt, char *md5Salt)
|
|||||||
static long
|
static long
|
||||||
PostmasterRandom(void)
|
PostmasterRandom(void)
|
||||||
{
|
{
|
||||||
static bool initialized = false;
|
/*
|
||||||
|
* Select a random seed at the time of first receiving a request.
|
||||||
if (!initialized)
|
*/
|
||||||
|
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);
|
srandom(random_seed);
|
||||||
initialized = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return random();
|
return random();
|
||||||
|
Loading…
Reference in New Issue
Block a user