proc.c 55.1 KB
Newer Older
1 2
/*-------------------------------------------------------------------------
 *
3
 * proc.c
4
 *	  routines to manage per-process shared memory data structure
5
 *
6
 * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
B
Add:  
Bruce Momjian 已提交
7
 * Portions Copyright (c) 1994, Regents of the University of California
8 9 10
 *
 *
 * IDENTIFICATION
11
 *	  src/backend/storage/lmgr/proc.c
12 13 14 15 16
 *
 *-------------------------------------------------------------------------
 */
/*
 * Interface (a):
17
 *		ProcSleep(), ProcWakeup(),
18 19
 *		ProcQueueAlloc() -- create a shm queue for sleeping processes
 *		ProcQueueInit() -- create a queue without allocing memory
20
 *
21 22
 * Waiting for a lock causes the backend to be put to sleep.  Whoever releases
 * the lock wakes the process up again (and gives it an error code so it knows
23 24 25 26
 * whether it was awoken on an error condition).
 *
 * Interface (b):
 *
27 28
 * ProcReleaseLocks -- frees the locks associated with current transaction
 *
29
 * ProcKill -- destroys the shared memory state (and locks)
30
 * associated with the process.
31
 */
32 33
#include "postgres.h"

34
#include <signal.h>
35 36
#include <unistd.h>
#include <sys/time.h>
M
Marc G. Fournier 已提交
37

38
#include "access/transam.h"
39
#include "access/twophase.h"
40
#include "access/xact.h"
41
#include "miscadmin.h"
42
#include "postmaster/autovacuum.h"
43
#include "replication/syncrep.h"
44
#include "storage/ipc.h"
45
#include "storage/lmgr.h"
46
#include "storage/pmsignal.h"
47
#include "storage/proc.h"
48
#include "storage/procarray.h"
49
#include "storage/procsignal.h"
50
#include "storage/spin.h"
51
#include "utils/timestamp.h"
52

53

54
/* GUC variables */
B
Bruce Momjian 已提交
55
int			DeadlockTimeout = 1000;
56
int			StatementTimeout = 0;
57
bool		log_lock_waits = false;
M
 
Marc G. Fournier 已提交
58

59
/* Pointer to this process's PGPROC and PGXACT structs, if any */
J
Jan Wieck 已提交
60
PGPROC	   *MyProc = NULL;
61
PGXACT	   *MyPgXact = NULL;
62 63

/*
J
Jan Wieck 已提交
64
 * This spinlock protects the freelist of recycled PGPROC structures.
65
 * We cannot use an LWLock because the LWLock manager depends on already
J
Jan Wieck 已提交
66
 * having a PGPROC and a wait semaphore!  But these structures are touched
67 68
 * relatively infrequently (only at backend startup or shutdown) and not for
 * very long, so a spinlock is okay.
69
 */
70
NON_EXEC_STATIC slock_t *ProcStructLock = NULL;
71

72
/* Pointers to shared-memory structures */
73
PROC_HDR *ProcGlobal = NULL;
74
NON_EXEC_STATIC PGPROC *AuxiliaryProcs = NULL;
75
PGPROC *PreparedXactProcs = NULL;
76

77 78
/* If we are waiting for a lock, this points to the associated LOCALLOCK */
static LOCALLOCK *lockAwaited = NULL;
79

80
/* Mark these volatile because they can be changed by signal handler */
81
static volatile bool standby_timeout_active = false;
82 83
static volatile bool statement_timeout_active = false;
static volatile bool deadlock_timeout_active = false;
84
static volatile DeadLockState deadlock_state = DS_NOT_YET_CHECKED;
85
volatile bool cancel_from_timeout = false;
B
Bruce Momjian 已提交
86

87 88 89
/* timeout_start_time is set when log_lock_waits is true */
static TimestampTz timeout_start_time;

90
/* statement_fin_time is valid only if statement_timeout_active is true */
91
static TimestampTz statement_fin_time;
92
static TimestampTz statement_fin_time2; /* valid only in recovery */
93 94


95
static void RemoveProcFromArray(int code, Datum arg);
96
static void ProcKill(int code, Datum arg);
97
static void AuxiliaryProcKill(int code, Datum arg);
98
static bool CheckStatementTimeout(void);
99
static bool CheckStandbyTimeout(void);
100

V
Vadim B. Mikheev 已提交
101

102 103 104
/*
 * Report shared-memory space needed by InitProcGlobal.
 */
105
Size
106
ProcGlobalShmemSize(void)
107
{
108 109 110 111
	Size		size = 0;

	/* ProcGlobal */
	size = add_size(size, sizeof(PROC_HDR));
112
	/* MyProcs, including autovacuum workers and launcher */
113
	size = add_size(size, mul_size(MaxBackends, sizeof(PGPROC)));
114 115 116 117
	/* AuxiliaryProcs */
	size = add_size(size, mul_size(NUM_AUXILIARY_PROCS, sizeof(PGPROC)));
	/* Prepared xacts */
	size = add_size(size, mul_size(max_prepared_xacts, sizeof(PGPROC)));
118 119
	/* ProcStructLock */
	size = add_size(size, sizeof(slock_t));
120

121 122 123 124
	size = add_size(size, mul_size(MaxBackends, sizeof(PGXACT)));
	size = add_size(size, mul_size(NUM_AUXILIARY_PROCS, sizeof(PGXACT)));
	size = add_size(size, mul_size(max_prepared_xacts, sizeof(PGXACT)));

125 126 127
	return size;
}

128 129 130 131
/*
 * Report number of semaphores needed by InitProcGlobal.
 */
int
132
ProcGlobalSemas(void)
133
{
134 135 136 137
	/*
	 * We need a sema per backend (including autovacuum), plus one for each
	 * auxiliary process.
	 */
138
	return MaxBackends + NUM_AUXILIARY_PROCS;
139 140
}

141 142
/*
 * InitProcGlobal -
143 144
 *	  Initialize the global process table during postmaster or standalone
 *	  backend startup.
145
 *
146
 *	  We also create all the per-process semaphores we will need to support
147 148 149 150 151 152 153
 *	  the requested number of backends.  We used to allocate semaphores
 *	  only when backends were actually started up, but that is bad because
 *	  it lets Postgres fail under load --- a lot of Unix systems are
 *	  (mis)configured with small limits on the number of semaphores, and
 *	  running out when trying to start another backend is a common failure.
 *	  So, now we grab enough semaphores to support the desired max number
 *	  of backends immediately at initialization --- if the sysadmin has set
154 155
 *	  MaxConnections or autovacuum_max_workers higher than his kernel will
 *	  support, he'll find out sooner rather than later.
156 157 158 159
 *
 *	  Another reason for creating semaphores here is that the semaphore
 *	  implementation typically requires us to create semaphores in the
 *	  postmaster, not in backends.
160 161
 *
 * Note: this is NOT called by individual backends under a postmaster,
162
 * not even in the EXEC_BACKEND case.  The ProcGlobal and AuxiliaryProcs
163
 * pointers must be propagated specially for EXEC_BACKEND operation.
164 165
 */
void
166
InitProcGlobal(void)
167
{
168
	PGPROC	   *procs;
169
	PGXACT	   *pgxacts;
170 171
	int			i,
				j;
172
	bool		found;
173
	uint32		TotalProcs = MaxBackends + NUM_AUXILIARY_PROCS + max_prepared_xacts;
174

175
	/* Create the ProcGlobal shared structure */
176
	ProcGlobal = (PROC_HDR *)
177 178
		ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &found);
	Assert(!found);
179

180 181 182
	/*
	 * Initialize the data structures.
	 */
R
Robert Haas 已提交
183
	ProcGlobal->spins_per_delay = DEFAULT_SPINS_PER_DELAY;
184 185
	ProcGlobal->freeProcs = NULL;
	ProcGlobal->autovacFreeProcs = NULL;
186 187 188
	ProcGlobal->startupProc = NULL;
	ProcGlobal->startupProcPid = 0;
	ProcGlobal->startupBufferPinWaitBufId = -1;
189 190
	ProcGlobal->walwriterLatch = NULL;
	ProcGlobal->checkpointerLatch = NULL;
191

192
	/*
193 194 195 196 197
	 * Create and initialize all the PGPROC structures we'll need.  There are
	 * four separate consumers: (1) normal backends, (2) autovacuum workers
	 * and the autovacuum launcher, (3) auxiliary processes, and (4) prepared
	 * transactions.  Each PGPROC structure is dedicated to exactly one of
	 * these purposes, and they do not move between groups.
198
	 */
R
Robert Haas 已提交
199
	procs = (PGPROC *) ShmemAlloc(TotalProcs * sizeof(PGPROC));
200 201
	ProcGlobal->allProcs = procs;
	ProcGlobal->allProcCount = TotalProcs;
202 203 204 205
	if (!procs)
		ereport(FATAL,
				(errcode(ERRCODE_OUT_OF_MEMORY),
				 errmsg("out of shared memory")));
R
Robert Haas 已提交
206
	MemSet(procs, 0, TotalProcs * sizeof(PGPROC));
207 208 209 210 211 212

	/*
	 * Also allocate a separate array of PGXACT structures.  This is separate
	 * from the main PGPROC array so that the most heavily accessed data is
	 * stored contiguously in memory in as few cache lines as possible. This
	 * provides significant performance benefits, especially on a
213
	 * multiprocessor system.  There is one PGXACT structure for every PGPROC
214 215 216 217 218 219
	 * structure.
	 */
	pgxacts = (PGXACT *) ShmemAlloc(TotalProcs * sizeof(PGXACT));
	MemSet(pgxacts, 0, TotalProcs * sizeof(PGXACT));
	ProcGlobal->allPgXact = pgxacts;

R
Robert Haas 已提交
220
	for (i = 0; i < TotalProcs; i++)
221
	{
R
Robert Haas 已提交
222
		/* Common initialization for all PGPROCs, regardless of type. */
223

224 225 226 227 228 229 230 231 232 233 234 235
		/*
		 * Set up per-PGPROC semaphore, latch, and backendLock. Prepared
		 * xact dummy PGPROCs don't need these though - they're never
		 * associated with a real process
		 */
		if (i < MaxBackends + NUM_AUXILIARY_PROCS)
		{
			PGSemaphoreCreate(&(procs[i].sem));
			InitSharedLatch(&(procs[i].procLatch));
			procs[i].backendLock = LWLockAssign();
		}
		procs[i].pgprocno = i;
R
Robert Haas 已提交
236 237 238 239 240 241

		/*
		 * Newly created PGPROCs for normal backends or for autovacuum must
		 * be queued up on the appropriate free list.  Because there can only
		 * ever be a small, fixed number of auxiliary processes, no free
		 * list is used in that case; InitAuxiliaryProcess() instead uses a
242 243
		 * linear search.  PGPROCs for prepared transactions are added to a
		 * free list by TwoPhaseShmemInit().
R
Robert Haas 已提交
244 245 246 247 248 249 250 251 252 253 254 255 256
		 */
		if (i < MaxConnections)
		{
			/* PGPROC for normal backend, add to freeProcs list */
			procs[i].links.next = (SHM_QUEUE *) ProcGlobal->freeProcs;
			ProcGlobal->freeProcs = &procs[i];
		}
		else if (i < MaxBackends)
		{
			/* PGPROC for AV launcher/worker, add to autovacFreeProcs list */
			procs[i].links.next = (SHM_QUEUE *) ProcGlobal->autovacFreeProcs;
			ProcGlobal->autovacFreeProcs = &procs[i];
		}
257 258 259 260

		/* Initialize myProcLocks[] shared memory queues. */
		for (j = 0; j < NUM_LOCK_PARTITIONS; j++)
			SHMQueueInit(&(procs[i].myProcLocks[j]));
261 262
	}

263
	/*
264 265
	 * Save pointers to the blocks of PGPROC structures reserved for
	 * auxiliary processes and prepared transactions.
266
	 */
R
Robert Haas 已提交
267
	AuxiliaryProcs = &procs[MaxBackends];
268
	PreparedXactProcs = &procs[MaxBackends + NUM_AUXILIARY_PROCS];
269 270 271 272

	/* Create ProcStructLock spinlock, too */
	ProcStructLock = (slock_t *) ShmemAlloc(sizeof(slock_t));
	SpinLockInit(ProcStructLock);
273 274
}

275
/*
276
 * InitProcess -- initialize a per-process data structure for this backend
277 278
 */
void
279
InitProcess(void)
280
{
281 282
	/* use volatile pointer to prevent code rearrangement */
	volatile PROC_HDR *procglobal = ProcGlobal;
283 284

	/*
285 286
	 * ProcGlobal should be set up already (if we are a backend, we inherit
	 * this by fork() or EXEC_BACKEND mechanism from the postmaster).
287
	 */
288
	if (procglobal == NULL)
289
		elog(PANIC, "proc header uninitialized");
290 291

	if (MyProc != NULL)
292
		elog(ERROR, "you already exist");
293

294
	/*
B
Bruce Momjian 已提交
295 296
	 * Try to get a proc struct from the free list.  If this fails, we must be
	 * out of PGPROC structures (not to mention semaphores).
297
	 *
B
Bruce Momjian 已提交
298 299
	 * While we are holding the ProcStructLock, also copy the current shared
	 * estimate of spins_per_delay to local storage.
300
	 */
301
	SpinLockAcquire(ProcStructLock);
302

303 304
	set_spins_per_delay(procglobal->spins_per_delay);

305
	if (IsAnyAutoVacuumProcess())
306
		MyProc = procglobal->autovacFreeProcs;
307
	else
308
		MyProc = procglobal->freeProcs;
309

310
	if (MyProc != NULL)
311
	{
312
		if (IsAnyAutoVacuumProcess())
313
			procglobal->autovacFreeProcs = (PGPROC *) MyProc->links.next;
314
		else
315
			procglobal->freeProcs = (PGPROC *) MyProc->links.next;
316
		SpinLockRelease(ProcStructLock);
317 318 319 320
	}
	else
	{
		/*
B
Bruce Momjian 已提交
321 322
		 * If we reach here, all the PGPROCs are in use.  This is one of the
		 * possible places to detect "too many backends", so give the standard
323 324
		 * error message.  XXX do we need to give a different failure message
		 * in the autovacuum case?
325
		 */
326
		SpinLockRelease(ProcStructLock);
327 328 329
		ereport(FATAL,
				(errcode(ERRCODE_TOO_MANY_CONNECTIONS),
				 errmsg("sorry, too many clients already")));
330
	}
331
	MyPgXact = &ProcGlobal->allPgXact[MyProc->pgprocno];
332

333 334
	/*
	 * Now that we have a PGPROC, mark ourselves as an active postmaster
335
	 * child; this is so that the postmaster can detect it if we exit without
336 337
	 * cleaning up.  (XXX autovac launcher currently doesn't participate in
	 * this; it probably should.)
338
	 */
339
	if (IsUnderPostmaster && !IsAutoVacuumLauncherProcess())
340
		MarkPostmasterChildActive();
341

342
	/*
343 344
	 * Initialize all fields of MyProc, except for those previously initialized
	 * by InitProcGlobal.
345
	 */
346
	SHMQueueElemInit(&(MyProc->links));
347
	MyProc->waitStatus = STATUS_OK;
348
	MyProc->lxid = InvalidLocalTransactionId;
349 350
	MyPgXact->xid = InvalidTransactionId;
	MyPgXact->xmin = InvalidTransactionId;
351
	MyProc->pid = MyProcPid;
352 353
	/* backendId, databaseId and roleId will be filled in later */
	MyProc->backendId = InvalidBackendId;
354
	MyProc->databaseId = InvalidOid;
355
	MyProc->roleId = InvalidOid;
356 357
	MyPgXact->inCommit = false;
	MyPgXact->vacuumFlags = 0;
358
	/* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
359
	if (IsAutoVacuumWorkerProcess())
360
		MyPgXact->vacuumFlags |= PROC_IS_AUTOVACUUM;
361
	MyProc->lwWaiting = false;
362
	MyProc->lwWaitMode = 0;
363
	MyProc->lwWaitLink = NULL;
364
	MyProc->waitLock = NULL;
365
	MyProc->waitProcLock = NULL;
366 367 368 369 370 371 372 373 374 375
#ifdef USE_ASSERT_CHECKING
	if (assert_enabled)
	{
		int i;

		/* Last process should have released all locks. */
		for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
			Assert(SHMQueueEmpty(&(MyProc->myProcLocks[i])));
	}
#endif
376
	MyProc->recoveryConflictPending = false;
377

378
	/* Initialize fields for sync rep */
379 380 381 382
	MyProc->waitLSN.xlogid = 0;
	MyProc->waitLSN.xrecoff = 0;
	MyProc->syncRepState = SYNC_REP_NOT_WAITING;
	SHMQueueElemInit(&(MyProc->syncRepLinks));
383 384 385 386 387 388

	/*
	 * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch.
	 * Note that there's no particular need to do ResetLatch here.
	 */
	OwnLatch(&MyProc->procLatch);
389

390
	/*
391
	 * We might be reusing a semaphore that belonged to a failed process. So
B
Bruce Momjian 已提交
392
	 * be careful and reinitialize its value here.	(This is not strictly
393
	 * necessary anymore, but seems like a good idea for cleanliness.)
394
	 */
395
	PGSemaphoreReset(&MyProc->sem);
396

397
	/*
398
	 * Arrange to clean up at backend exit.
399
	 */
400
	on_shmem_exit(ProcKill, 0);
401 402

	/*
B
Bruce Momjian 已提交
403 404
	 * Now that we have a PGPROC, we could try to acquire locks, so initialize
	 * the deadlock checker.
405 406
	 */
	InitDeadLockChecking();
407 408
}

409 410 411 412
/*
 * InitProcessPhase2 -- make MyProc visible in the shared ProcArray.
 *
 * This is separate from InitProcess because we can't acquire LWLocks until
413 414
 * we've created a PGPROC, but in the EXEC_BACKEND case ProcArrayAdd won't
 * work until after we've done CreateSharedMemoryAndSemaphores.
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
 */
void
InitProcessPhase2(void)
{
	Assert(MyProc != NULL);

	/*
	 * Add our PGPROC to the PGPROC array in shared memory.
	 */
	ProcArrayAdd(MyProc);

	/*
	 * Arrange to clean that up at backend exit.
	 */
	on_shmem_exit(RemoveProcFromArray, 0);
}

432
/*
433
 * InitAuxiliaryProcess -- create a per-auxiliary-process data structure
434
 *
435 436
 * This is called by bgwriter and similar processes so that they will have a
 * MyProc value that's real enough to let them wait for LWLocks.  The PGPROC
437
 * and sema that are assigned are one of the extra ones created during
438
 * InitProcGlobal.
439
 *
440
 * Auxiliary processes are presently not expected to wait for real (lockmgr)
441
 * locks, so we need not set up the deadlock checker.  They are never added
B
Bruce Momjian 已提交
442
 * to the ProcArray or the sinval messaging mechanism, either.	They also
443 444
 * don't get a VXID assigned, since this is only useful when we actually
 * hold lockmgr locks.
445 446 447 448 449
 *
 * Startup process however uses locks but never waits for them in the
 * normal backend sense. Startup process also takes part in sinval messaging
 * as a sendOnly process, so never reads messages from sinval queue. So
 * Startup process does have a VXID and does show up in pg_locks.
450 451
 */
void
452
InitAuxiliaryProcess(void)
453
{
454
	PGPROC	   *auxproc;
455
	int			proctype;
J
Jan Wieck 已提交
456

457
	/*
458 459
	 * ProcGlobal should be set up already (if we are a backend, we inherit
	 * this by fork() or EXEC_BACKEND mechanism from the postmaster).
460
	 */
461
	if (ProcGlobal == NULL || AuxiliaryProcs == NULL)
462
		elog(PANIC, "proc header uninitialized");
463 464

	if (MyProc != NULL)
465
		elog(ERROR, "you already exist");
466

467
	/*
468
	 * We use the ProcStructLock to protect assignment and releasing of
469
	 * AuxiliaryProcs entries.
470
	 *
B
Bruce Momjian 已提交
471 472
	 * While we are holding the ProcStructLock, also copy the current shared
	 * estimate of spins_per_delay to local storage.
473 474 475 476 477
	 */
	SpinLockAcquire(ProcStructLock);

	set_spins_per_delay(ProcGlobal->spins_per_delay);

478
	/*
479
	 * Find a free auxproc ... *big* trouble if there isn't one ...
480
	 */
481
	for (proctype = 0; proctype < NUM_AUXILIARY_PROCS; proctype++)
482
	{
483 484
		auxproc = &AuxiliaryProcs[proctype];
		if (auxproc->pid == 0)
485 486
			break;
	}
487
	if (proctype >= NUM_AUXILIARY_PROCS)
488 489
	{
		SpinLockRelease(ProcStructLock);
490
		elog(FATAL, "all AuxiliaryProcs are in use");
491
	}
492

493
	/* Mark auxiliary proc as in use by me */
494
	/* use volatile pointer to prevent code rearrangement */
495
	((volatile PGPROC *) auxproc)->pid = MyProcPid;
496

497
	MyProc = auxproc;
498
	MyPgXact = &ProcGlobal->allPgXact[auxproc->pgprocno];
499 500 501

	SpinLockRelease(ProcStructLock);

502
	/*
503 504
	 * Initialize all fields of MyProc, except for those previously initialized
	 * by InitProcGlobal.
505 506
	 */
	SHMQueueElemInit(&(MyProc->links));
507
	MyProc->waitStatus = STATUS_OK;
508
	MyProc->lxid = InvalidLocalTransactionId;
509 510
	MyPgXact->xid = InvalidTransactionId;
	MyPgXact->xmin = InvalidTransactionId;
511
	MyProc->backendId = InvalidBackendId;
512
	MyProc->databaseId = InvalidOid;
513
	MyProc->roleId = InvalidOid;
514 515
	MyPgXact->inCommit = false;
	MyPgXact->vacuumFlags = 0;
516
	MyProc->lwWaiting = false;
517
	MyProc->lwWaitMode = 0;
518 519
	MyProc->lwWaitLink = NULL;
	MyProc->waitLock = NULL;
520
	MyProc->waitProcLock = NULL;
521 522 523 524 525 526 527 528 529 530
#ifdef USE_ASSERT_CHECKING
	if (assert_enabled)
	{
		int i;

		/* Last process should have released all locks. */
		for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
			Assert(SHMQueueEmpty(&(MyProc->myProcLocks[i])));
	}
#endif
531

532 533 534 535 536 537
	/*
	 * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch.
	 * Note that there's no particular need to do ResetLatch here.
	 */
	OwnLatch(&MyProc->procLatch);

538
	/*
B
Bruce Momjian 已提交
539
	 * We might be reusing a semaphore that belonged to a failed process. So
B
Bruce Momjian 已提交
540
	 * be careful and reinitialize its value here.	(This is not strictly
541
	 * necessary anymore, but seems like a good idea for cleanliness.)
542
	 */
543
	PGSemaphoreReset(&MyProc->sem);
544 545 546 547

	/*
	 * Arrange to clean up at process exit.
	 */
548
	on_shmem_exit(AuxiliaryProcKill, Int32GetDatum(proctype));
549 550
}

551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568
/*
 * Record the PID and PGPROC structures for the Startup process, for use in
 * ProcSendSignal().  See comments there for further explanation.
 */
void
PublishStartupProcessInformation(void)
{
	/* use volatile pointer to prevent code rearrangement */
	volatile PROC_HDR *procglobal = ProcGlobal;

	SpinLockAcquire(ProcStructLock);

	procglobal->startupProc = MyProc;
	procglobal->startupProcPid = MyProcPid;

	SpinLockRelease(ProcStructLock);
}

569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593
/*
 * Used from bufgr to share the value of the buffer that Startup waits on,
 * or to reset the value to "not waiting" (-1). This allows processing
 * of recovery conflicts for buffer pins. Set is made before backends look
 * at this value, so locking not required, especially since the set is
 * an atomic integer set operation.
 */
void
SetStartupBufferPinWaitBufId(int bufid)
{
	/* use volatile pointer to prevent code rearrangement */
	volatile PROC_HDR *procglobal = ProcGlobal;

	procglobal->startupBufferPinWaitBufId = bufid;
}

/*
 * Used by backends when they receive a request to check for buffer pin waits.
 */
int
GetStartupBufferPinWaitBufId(void)
{
	/* use volatile pointer to prevent code rearrangement */
	volatile PROC_HDR *procglobal = ProcGlobal;

594
	return procglobal->startupBufferPinWaitBufId;
595 596
}

597 598 599 600 601 602 603 604 605
/*
 * Check whether there are at least N free PGPROC objects.
 *
 * Note: this is designed on the assumption that N will generally be small.
 */
bool
HaveNFreeProcs(int n)
{
	PGPROC	   *proc;
B
Bruce Momjian 已提交
606

607 608 609 610 611
	/* use volatile pointer to prevent code rearrangement */
	volatile PROC_HDR *procglobal = ProcGlobal;

	SpinLockAcquire(ProcStructLock);

612
	proc = procglobal->freeProcs;
613

614
	while (n > 0 && proc != NULL)
615
	{
616
		proc = (PGPROC *) proc->links.next;
617 618 619 620 621 622 623 624
		n--;
	}

	SpinLockRelease(ProcStructLock);

	return (n <= 0);
}

625 626 627
/*
 * Check if the current process is awaiting a lock.
 */
628 629 630 631 632 633 634 635 636
bool
IsWaitingForLock(void)
{
	if (lockAwaited == NULL)
		return false;

	return true;
}

637
/*
638 639
 * Cancel any pending wait for lock, when aborting a transaction, and revert
 * any strong lock count acquisition for a lock being acquired.
640 641
 *
 * (Normally, this would only happen if we accept a cancel/die
642 643
 * interrupt while waiting; but an ereport(ERROR) before or during the lock
 * wait is within the realm of possibility, too.)
644
 */
645
void
646
LockErrorCleanup(void)
647
{
648 649
	LWLockId	partitionLock;

650 651
	AbortStrongLockAcquire();

652
	/* Nothing to do if we weren't waiting for a lock */
653
	if (lockAwaited == NULL)
654
		return;
655

656
	/* Turn off the deadlock timer, if it's still running (see ProcSleep) */
657
	disable_sig_alarm(false);
658 659

	/* Unlink myself from the wait queue, if on it (might not be anymore!) */
660
	partitionLock = LockHashPartitionLock(lockAwaited->hashcode);
661
	LWLockAcquire(partitionLock, LW_EXCLUSIVE);
662

663
	if (MyProc->links.next != NULL)
664 665
	{
		/* We could not have been granted the lock yet */
666
		RemoveFromWaitQueue(MyProc, lockAwaited->hashcode);
667 668 669 670 671
	}
	else
	{
		/*
		 * Somebody kicked us off the lock queue already.  Perhaps they
B
Bruce Momjian 已提交
672 673 674
		 * granted us the lock, or perhaps they detected a deadlock. If they
		 * did grant us the lock, we'd better remember it in our local lock
		 * table.
675
		 */
676 677
		if (MyProc->waitStatus == STATUS_OK)
			GrantAwaitedLock();
678 679
	}

680
	lockAwaited = NULL;
681

682
	LWLockRelease(partitionLock);
H
Hiroshi Inoue 已提交
683

684
	/*
685
	 * We used to do PGSemaphoreReset() here to ensure that our proc's wait
B
Bruce Momjian 已提交
686 687 688 689 690 691
	 * semaphore is reset to zero.	This prevented a leftover wakeup signal
	 * from remaining in the semaphore if someone else had granted us the lock
	 * we wanted before we were able to remove ourselves from the wait-list.
	 * However, now that ProcSleep loops until waitStatus changes, a leftover
	 * wakeup signal isn't harmful, and it seems not worth expending cycles to
	 * get rid of a signal that most likely isn't there.
692
	 */
H
Hiroshi Inoue 已提交
693
}
694

695

696
/*
697
 * ProcReleaseLocks() -- release locks associated with current transaction
698
 *			at main transaction commit or abort
699
 *
700
 * At main transaction commit, we release standard locks except session locks.
701
 * At main transaction abort, we release all locks including session locks.
702
 *
703 704 705
 * Advisory locks are released only if they are transaction-level;
 * session-level holds remain, whether this is a commit or not.
 *
706
 * At subtransaction commit, we don't release any locks (so this func is not
707
 * needed at all); we will defer the releasing to the parent transaction.
708
 * At subtransaction abort, we release all locks held by the subtransaction;
709 710
 * this is implemented by retail releasing of the locks under control of
 * the ResourceOwner mechanism.
711 712
 */
void
713
ProcReleaseLocks(bool isCommit)
714
{
715 716
	if (!MyProc)
		return;
717
	/* If waiting, get off wait queue (should only be needed after error) */
718
	LockErrorCleanup();
719
	/* Release standard locks, including session-level if aborting */
720
	LockReleaseAll(DEFAULT_LOCKMETHOD, !isCommit);
721
	/* Release transaction-level advisory locks */
722
	LockReleaseAll(USER_LOCKMETHOD, false);
723 724 725
}


726 727 728 729 730 731 732
/*
 * RemoveProcFromArray() -- Remove this process from the shared ProcArray.
 */
static void
RemoveProcFromArray(int code, Datum arg)
{
	Assert(MyProc != NULL);
733
	ProcArrayRemove(MyProc, InvalidTransactionId);
734 735
}

736 737
/*
 * ProcKill() -- Destroy the per-proc data structure for
738
 *		this process. Release any of its held LW locks.
739 740
 */
static void
741
ProcKill(int code, Datum arg)
742
{
743 744 745
	/* use volatile pointer to prevent code rearrangement */
	volatile PROC_HDR *procglobal = ProcGlobal;

746
	Assert(MyProc != NULL);
747

748 749 750
	/* Make sure we're out of the sync rep lists */
	SyncRepCleanupAtProcExit();

751 752 753 754 755 756 757 758 759 760 761
#ifdef USE_ASSERT_CHECKING
	if (assert_enabled)
	{
		int i;

		/* Last process should have released all locks. */
		for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
			Assert(SHMQueueEmpty(&(MyProc->myProcLocks[i])));
	}
#endif

762
	/*
B
Bruce Momjian 已提交
763 764
	 * Release any LW locks I am holding.  There really shouldn't be any, but
	 * it's cheap to check again before we cut the knees off the LWLock
765
	 * facility by releasing our PGPROC ...
766
	 */
767
	LWLockReleaseAll();
768

769 770 771
	/* Release ownership of the process's latch, too */
	DisownLatch(&MyProc->procLatch);

772
	SpinLockAcquire(ProcStructLock);
773

774 775
	/* Return PGPROC structure (and semaphore) to appropriate freelist */
	if (IsAnyAutoVacuumProcess())
776
	{
777 778
		MyProc->links.next = (SHM_QUEUE *) procglobal->autovacFreeProcs;
		procglobal->autovacFreeProcs = MyProc;
779 780 781
	}
	else
	{
782 783
		MyProc->links.next = (SHM_QUEUE *) procglobal->freeProcs;
		procglobal->freeProcs = MyProc;
784
	}
785

J
Jan Wieck 已提交
786
	/* PGPROC struct isn't mine anymore */
787
	MyProc = NULL;
788

789 790 791
	/* Update shared estimate of spins_per_delay */
	procglobal->spins_per_delay = update_spins_per_delay(procglobal->spins_per_delay);

792
	SpinLockRelease(ProcStructLock);
793

794 795
	/*
	 * This process is no longer present in shared memory in any meaningful
B
Bruce Momjian 已提交
796 797
	 * way, so tell the postmaster we've cleaned up acceptably well. (XXX
	 * autovac launcher should be included here someday)
798
	 */
799
	if (IsUnderPostmaster && !IsAutoVacuumLauncherProcess())
800 801
		MarkPostmasterChildInactive();

802 803
	/* wake autovac launcher if needed -- see comments in FreeWorkerInfo */
	if (AutovacuumLauncherPid != 0)
804
		kill(AutovacuumLauncherPid, SIGUSR2);
805 806 807
}

/*
808 809 810
 * AuxiliaryProcKill() -- Cut-down version of ProcKill for auxiliary
 *		processes (bgwriter, etc).	The PGPROC and sema are not released, only
 *		marked as not-in-use.
811 812
 */
static void
813
AuxiliaryProcKill(int code, Datum arg)
814
{
B
Bruce Momjian 已提交
815
	int			proctype = DatumGetInt32(arg);
816
	PGPROC	   *auxproc PG_USED_FOR_ASSERTS_ONLY;
J
Jan Wieck 已提交
817

818
	Assert(proctype >= 0 && proctype < NUM_AUXILIARY_PROCS);
J
Jan Wieck 已提交
819

820
	auxproc = &AuxiliaryProcs[proctype];
J
Jan Wieck 已提交
821

822
	Assert(MyProc == auxproc);
823

824
	/* Release any LW locks I am holding (see notes above) */
825 826
	LWLockReleaseAll();

827 828 829
	/* Release ownership of the process's latch, too */
	DisownLatch(&MyProc->procLatch);

830 831
	SpinLockAcquire(ProcStructLock);

832
	/* Mark auxiliary proc no longer in use */
833 834
	MyProc->pid = 0;

J
Jan Wieck 已提交
835
	/* PGPROC struct isn't mine anymore */
836
	MyProc = NULL;
837 838 839 840 841

	/* Update shared estimate of spins_per_delay */
	ProcGlobal->spins_per_delay = update_spins_per_delay(ProcGlobal->spins_per_delay);

	SpinLockRelease(ProcStructLock);
842 843
}

844

845 846
/*
 * ProcQueue package: routines for putting processes to sleep
847
 *		and  waking them up
848 849 850 851 852
 */

/*
 * ProcQueueAlloc -- alloc/attach to a shared memory process queue
 *
853 854
 * Returns: a pointer to the queue
 * Side Effects: Initializes the queue if it wasn't there before
855
 */
856
#ifdef NOT_USED
857
PROC_QUEUE *
858
ProcQueueAlloc(const char *name)
859
{
860
	PROC_QUEUE *queue;
861
	bool		found;
862

863 864 865
	queue = (PROC_QUEUE *)
		ShmemInitStruct(name, sizeof(PROC_QUEUE), &found);

866 867
	if (!found)
		ProcQueueInit(queue);
868

869
	return queue;
870
}
871
#endif
872 873 874 875 876

/*
 * ProcQueueInit -- initialize a shared memory process queue
 */
void
877
ProcQueueInit(PROC_QUEUE *queue)
878
{
879 880
	SHMQueueInit(&(queue->links));
	queue->size = 0;
881 882 883 884
}


/*
885
 * ProcSleep -- put a process to sleep on the specified lock
886
 *
887 888
 * Caller must have set MyProc->heldLocks to reflect locks already held
 * on the lockable object by this process (under all XIDs).
889
 *
890
 * The lock table's partition lock must be held at entry, and will be held
891
 * at exit.
892
 *
893
 * Result: STATUS_OK if we acquired the lock, STATUS_ERROR if not (deadlock).
894
 *
895
 * ASSUME: that no one will fiddle with the queue until after
896
 *		we release the partition lock.
897 898
 *
 * NOTES: The process queue is now a priority queue for locking.
899 900 901
 *
 * P() on the semaphore should put us to sleep.  The process
 * semaphore is normally zero, so when we try to acquire it, we sleep.
902 903
 */
int
904
ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
905
{
906 907 908
	LOCKMODE	lockmode = locallock->tag.mode;
	LOCK	   *lock = locallock->lock;
	PROCLOCK   *proclock = locallock->proclock;
909 910
	uint32		hashcode = locallock->hashcode;
	LWLockId	partitionLock = LockHashPartitionLock(hashcode);
911
	PROC_QUEUE *waitQueue = &(lock->waitProcs);
912
	LOCKMASK	myHeldLocks = MyProc->heldLocks;
913
	bool		early_deadlock = false;
B
Bruce Momjian 已提交
914
	bool		allow_autovacuum_cancel = true;
915
	int			myWaitStatus;
J
Jan Wieck 已提交
916
	PGPROC	   *proc;
917
	int			i;
918

919
	/*
920 921
	 * Determine where to add myself in the wait queue.
	 *
922 923 924 925
	 * Normally I should go at the end of the queue.  However, if I already
	 * hold locks that conflict with the request of any previous waiter, put
	 * myself in the queue just in front of the first such waiter. This is not
	 * a necessary step, since deadlock detection would move me to before that
B
Bruce Momjian 已提交
926 927
	 * waiter anyway; but it's relatively cheap to detect such a conflict
	 * immediately, and avoid delaying till deadlock timeout.
928
	 *
929 930
	 * Special case: if I find I should go in front of some waiter, check to
	 * see if I conflict with already-held locks or the requests before that
B
Bruce Momjian 已提交
931 932 933 934
	 * waiter.	If not, then just grant myself the requested lock immediately.
	 * This is the same as the test for immediate grant in LockAcquire, except
	 * we are only considering the part of the wait queue before my insertion
	 * point.
935 936
	 */
	if (myHeldLocks != 0)
V
Vadim B. Mikheev 已提交
937
	{
938
		LOCKMASK	aheadRequests = 0;
939

940
		proc = (PGPROC *) waitQueue->links.next;
941
		for (i = 0; i < waitQueue->size; i++)
V
Vadim B. Mikheev 已提交
942
		{
943
			/* Must he wait for me? */
B
Bruce Momjian 已提交
944
			if (lockMethodTable->conflictTab[proc->waitLockMode] & myHeldLocks)
V
Vadim B. Mikheev 已提交
945
			{
946
				/* Must I wait for him ? */
B
Bruce Momjian 已提交
947
				if (lockMethodTable->conflictTab[lockmode] & proc->heldLocks)
948
				{
949
					/*
B
Bruce Momjian 已提交
950 951 952 953 954
					 * Yes, so we have a deadlock.	Easiest way to clean up
					 * correctly is to call RemoveFromWaitQueue(), but we
					 * can't do that until we are *on* the wait queue. So, set
					 * a flag to check below, and break out of loop.  Also,
					 * record deadlock info for later message.
955
					 */
956
					RememberSimpleDeadLock(MyProc, lockmode, lock, proc);
957 958
					early_deadlock = true;
					break;
959
				}
960
				/* I must go before this waiter.  Check special case. */
B
Bruce Momjian 已提交
961
				if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
962 963 964
					LockCheckConflicts(lockMethodTable,
									   lockmode,
									   lock,
965
									   proclock,
966
									   MyProc) == STATUS_OK)
967
				{
968
					/* Skip the wait and just grant myself the lock. */
969
					GrantLock(lock, proclock, lockmode);
970
					GrantAwaitedLock();
971
					return STATUS_OK;
972 973
				}
				/* Break out of loop to put myself before him */
V
Vadim B. Mikheev 已提交
974
				break;
975
			}
976
			/* Nope, so advance to next waiter */
977
			aheadRequests |= LOCKBIT_ON(proc->waitLockMode);
978
			proc = (PGPROC *) proc->links.next;
V
Vadim B. Mikheev 已提交
979
		}
B
Bruce Momjian 已提交
980

981
		/*
B
Bruce Momjian 已提交
982 983
		 * If we fall out of loop normally, proc points to waitQueue head, so
		 * we will insert at tail of queue as desired.
984
		 */
985 986 987 988
	}
	else
	{
		/* I hold no locks, so I can't push in front of anyone. */
J
Jan Wieck 已提交
989
		proc = (PGPROC *) &(waitQueue->links);
V
Vadim B. Mikheev 已提交
990
	}
991

992
	/*
B
Bruce Momjian 已提交
993
	 * Insert self into queue, ahead of the given proc (or at tail of queue).
994
	 */
995
	SHMQueueInsertBefore(&(proc->links), &(MyProc->links));
B
Bruce Momjian 已提交
996
	waitQueue->size++;
997

998
	lock->waitMask |= LOCKBIT_ON(lockmode);
999

J
Jan Wieck 已提交
1000
	/* Set up wait information in PGPROC object, too */
1001
	MyProc->waitLock = lock;
1002
	MyProc->waitProcLock = proclock;
1003 1004
	MyProc->waitLockMode = lockmode;

1005
	MyProc->waitStatus = STATUS_WAITING;
1006 1007

	/*
B
Bruce Momjian 已提交
1008 1009 1010
	 * If we detected deadlock, give up without waiting.  This must agree with
	 * CheckDeadLock's recovery code, except that we shouldn't release the
	 * semaphore since we haven't tried to lock it yet.
1011 1012 1013
	 */
	if (early_deadlock)
	{
1014
		RemoveFromWaitQueue(MyProc, hashcode);
1015 1016
		return STATUS_ERROR;
	}
1017

1018
	/* mark that we are waiting for a lock */
1019
	lockAwaited = locallock;
1020

1021
	/*
1022
	 * Release the lock table's partition lock.
1023
	 *
1024
	 * NOTE: this may also cause us to exit critical-section state, possibly
B
Bruce Momjian 已提交
1025 1026
	 * allowing a cancel/die interrupt to be accepted. This is OK because we
	 * have recorded the fact that we are waiting for a lock, and so
1027
	 * LockErrorCleanup will clean up if cancel/die happens.
1028
	 */
1029
	LWLockRelease(partitionLock);
1030

1031 1032 1033 1034 1035 1036 1037 1038 1039
	/*
	 * Also, now that we will successfully clean up after an ereport, it's
	 * safe to check to see if there's a buffer pin deadlock against the
	 * Startup process.  Of course, that's only necessary if we're doing
	 * Hot Standby and are not the Startup process ourselves.
	 */
	if (RecoveryInProgress() && !InRecovery)
		CheckRecoveryConflictDeadlock();

1040 1041 1042
	/* Reset deadlock_state before enabling the signal handler */
	deadlock_state = DS_NOT_YET_CHECKED;

1043
	/*
B
Bruce Momjian 已提交
1044 1045 1046 1047
	 * Set timer so we can wake up after awhile and check for a deadlock. If a
	 * deadlock is detected, the handler releases the process's semaphore and
	 * sets MyProc->waitStatus = STATUS_ERROR, allowing us to know that we
	 * must report failure rather than success.
1048
	 *
1049 1050
	 * By delaying the check until we've waited for a bit, we can avoid
	 * running the rather expensive deadlock-check code in most cases.
1051
	 */
1052
	if (!enable_sig_alarm(DeadlockTimeout, false))
1053
		elog(FATAL, "could not set timer for process wakeup");
1054

1055
	/*
1056
	 * If someone wakes us between LWLockRelease and PGSemaphoreLock,
B
Bruce Momjian 已提交
1057
	 * PGSemaphoreLock will not block.	The wakeup is "saved" by the semaphore
B
Bruce Momjian 已提交
1058 1059 1060 1061 1062
	 * implementation.	While this is normally good, there are cases where a
	 * saved wakeup might be leftover from a previous operation (for example,
	 * we aborted ProcWaitForSignal just before someone did ProcSendSignal).
	 * So, loop to wait again if the waitStatus shows we haven't been granted
	 * nor denied the lock yet.
1063
	 *
1064 1065 1066 1067 1068 1069
	 * We pass interruptOK = true, which eliminates a window in which
	 * cancel/die interrupts would be held off undesirably.  This is a promise
	 * that we don't mind losing control to a cancel/die interrupt here.  We
	 * don't, because we have no shared-state-change work to do after being
	 * granted the lock (the grantor did it all).  We do have to worry about
	 * updating the locallock table, but if we lose control to an error,
1070
	 * LockErrorCleanup will fix that up.
1071
	 */
B
Bruce Momjian 已提交
1072 1073
	do
	{
1074
		PGSemaphoreLock(&MyProc->sem, true);
1075

1076 1077
		/*
		 * waitStatus could change from STATUS_WAITING to something else
B
Bruce Momjian 已提交
1078
		 * asynchronously.	Read it just once per loop to prevent surprising
1079 1080 1081 1082
		 * behavior (such as missing log messages).
		 */
		myWaitStatus = MyProc->waitStatus;

1083 1084
		/*
		 * If we are not deadlocked, but are waiting on an autovacuum-induced
B
Bruce Momjian 已提交
1085
		 * task, send a signal to interrupt it.
1086 1087 1088
		 */
		if (deadlock_state == DS_BLOCKED_BY_AUTOVACUUM && allow_autovacuum_cancel)
		{
B
Bruce Momjian 已提交
1089
			PGPROC	   *autovac = GetBlockingAutoVacuumPgproc();
1090
			PGXACT	   *autovac_pgxact = &ProcGlobal->allPgXact[autovac->pgprocno];
1091 1092 1093 1094 1095 1096 1097 1098

			LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);

			/*
			 * Only do it if the worker is not working to protect against Xid
			 * wraparound.
			 */
			if ((autovac != NULL) &&
1099 1100
				(autovac_pgxact->vacuumFlags & PROC_IS_AUTOVACUUM) &&
				!(autovac_pgxact->vacuumFlags & PROC_VACUUM_FOR_WRAPAROUND))
1101
			{
B
Bruce Momjian 已提交
1102
				int			pid = autovac->pid;
1103

P
Peter Eisentraut 已提交
1104
				elog(DEBUG2, "sending cancel to blocking autovacuum PID %d",
1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125
					 pid);

				/* don't hold the lock across the kill() syscall */
				LWLockRelease(ProcArrayLock);

				/* send the autovacuum worker Back to Old Kent Road */
				if (kill(pid, SIGINT) < 0)
				{
					/* Just a warning to allow multiple callers */
					ereport(WARNING,
							(errmsg("could not send signal to process %d: %m",
									pid)));
				}
			}
			else
				LWLockRelease(ProcArrayLock);

			/* prevent signal from being resent more than once */
			allow_autovacuum_cancel = false;
		}

1126 1127 1128 1129
		/*
		 * If awoken after the deadlock check interrupt has run, and
		 * log_lock_waits is on, then report about the wait.
		 */
1130
		if (log_lock_waits && deadlock_state != DS_NOT_YET_CHECKED)
1131
		{
1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149
			StringInfoData buf;
			const char *modename;
			long		secs;
			int			usecs;
			long		msecs;

			initStringInfo(&buf);
			DescribeLockTag(&buf, &locallock->tag.lock);
			modename = GetLockmodeName(locallock->tag.lock.locktag_lockmethodid,
									   lockmode);
			TimestampDifference(timeout_start_time, GetCurrentTimestamp(),
								&secs, &usecs);
			msecs = secs * 1000 + usecs / 1000;
			usecs = usecs % 1000;

			if (deadlock_state == DS_SOFT_DEADLOCK)
				ereport(LOG,
						(errmsg("process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms",
B
Bruce Momjian 已提交
1150
							  MyProcPid, modename, buf.data, msecs, usecs)));
1151
			else if (deadlock_state == DS_HARD_DEADLOCK)
1152
			{
1153
				/*
B
Bruce Momjian 已提交
1154 1155 1156 1157
				 * This message is a bit redundant with the error that will be
				 * reported subsequently, but in some cases the error report
				 * might not make it to the log (eg, if it's caught by an
				 * exception handler), and we want to ensure all long-wait
1158 1159 1160 1161
				 * events get logged.
				 */
				ereport(LOG,
						(errmsg("process %d detected deadlock while waiting for %s on %s after %ld.%03d ms",
B
Bruce Momjian 已提交
1162
							  MyProcPid, modename, buf.data, msecs, usecs)));
1163
			}
1164 1165 1166 1167

			if (myWaitStatus == STATUS_WAITING)
				ereport(LOG,
						(errmsg("process %d still waiting for %s on %s after %ld.%03d ms",
B
Bruce Momjian 已提交
1168
							  MyProcPid, modename, buf.data, msecs, usecs)));
1169 1170
			else if (myWaitStatus == STATUS_OK)
				ereport(LOG,
B
Bruce Momjian 已提交
1171 1172
					(errmsg("process %d acquired %s on %s after %ld.%03d ms",
							MyProcPid, modename, buf.data, msecs, usecs)));
1173 1174 1175
			else
			{
				Assert(myWaitStatus == STATUS_ERROR);
B
Bruce Momjian 已提交
1176

1177 1178
				/*
				 * Currently, the deadlock checker always kicks its own
B
Bruce Momjian 已提交
1179 1180 1181 1182 1183
				 * process, which means that we'll only see STATUS_ERROR when
				 * deadlock_state == DS_HARD_DEADLOCK, and there's no need to
				 * print redundant messages.  But for completeness and
				 * future-proofing, print a message if it looks like someone
				 * else kicked us off the lock.
1184 1185 1186 1187
				 */
				if (deadlock_state != DS_HARD_DEADLOCK)
					ereport(LOG,
							(errmsg("process %d failed to acquire %s on %s after %ld.%03d ms",
B
Bruce Momjian 已提交
1188
							  MyProcPid, modename, buf.data, msecs, usecs)));
1189 1190 1191
			}

			/*
B
Bruce Momjian 已提交
1192 1193
			 * At this point we might still need to wait for the lock. Reset
			 * state so we don't print the above messages again.
1194 1195 1196 1197
			 */
			deadlock_state = DS_NO_DEADLOCK;

			pfree(buf.data);
1198
		}
1199
	} while (myWaitStatus == STATUS_WAITING);
1200

1201
	/*
1202
	 * Disable the timer, if it's still running
B
Bruce Momjian 已提交
1203
	 */
1204
	if (!disable_sig_alarm(false))
1205
		elog(FATAL, "could not disable timer for process wakeup");
B
Bruce Momjian 已提交
1206

1207
	/*
B
Bruce Momjian 已提交
1208 1209 1210
	 * Re-acquire the lock table's partition lock.  We have to do this to hold
	 * off cancel/die interrupts before we can mess with lockAwaited (else we
	 * might have a missed or duplicated locallock update).
1211
	 */
1212
	LWLockAcquire(partitionLock, LW_EXCLUSIVE);
1213 1214

	/*
1215
	 * We no longer want LockErrorCleanup to do anything.
1216
	 */
1217
	lockAwaited = NULL;
1218

1219
	/*
1220
	 * If we got the lock, be sure to remember it in the locallock table.
1221
	 */
1222
	if (MyProc->waitStatus == STATUS_OK)
1223
		GrantAwaitedLock();
1224

1225 1226 1227 1228
	/*
	 * We don't have to do anything else, because the awaker did all the
	 * necessary update of the lock table and MyProc.
	 */
1229
	return MyProc->waitStatus;
1230 1231 1232 1233 1234 1235
}


/*
 * ProcWakeup -- wake up a process by releasing its private semaphore.
 *
1236
 *	 Also remove the process from the wait queue and set its links invalid.
1237
 *	 RETURN: the next process in the wait queue.
1238
 *
1239 1240
 * The appropriate lock partition lock must be held by caller.
 *
1241 1242 1243
 * XXX: presently, this code is only used for the "success" case, and only
 * works correctly for that case.  To clean up in failure case, would need
 * to twiddle the lock's request counts too --- see RemoveFromWaitQueue.
1244
 * Hence, in practice the waitStatus parameter must be STATUS_OK.
1245
 */
J
Jan Wieck 已提交
1246
PGPROC *
1247
ProcWakeup(PGPROC *proc, int waitStatus)
1248
{
J
Jan Wieck 已提交
1249
	PGPROC	   *retProc;
1250

1251
	/* Proc should be sleeping ... */
1252 1253
	if (proc->links.prev == NULL ||
		proc->links.next == NULL)
1254
		return NULL;
1255
	Assert(proc->waitStatus == STATUS_WAITING);
1256

1257
	/* Save next process before we zap the list link */
1258
	retProc = (PGPROC *) proc->links.next;
1259

1260
	/* Remove process from wait queue */
1261
	SHMQueueDelete(&(proc->links));
1262
	(proc->waitLock->waitProcs.size)--;
1263

1264 1265
	/* Clean up process' state and pass it the ok/fail signal */
	proc->waitLock = NULL;
1266
	proc->waitProcLock = NULL;
1267
	proc->waitStatus = waitStatus;
1268

1269
	/* And awaken it */
1270
	PGSemaphoreUnlock(&proc->sem);
1271 1272

	return retProc;
1273 1274 1275 1276
}

/*
 * ProcLockWakeup -- routine for waking up processes when a lock is
1277 1278
 *		released (or a prior waiter is aborted).  Scan all waiters
 *		for lock, waken any that are no longer blocked.
1279 1280
 *
 * The appropriate lock partition lock must be held by caller.
1281
 */
1282
void
1283
ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock)
1284
{
1285 1286
	PROC_QUEUE *waitQueue = &(lock->waitProcs);
	int			queue_size = waitQueue->size;
J
Jan Wieck 已提交
1287
	PGPROC	   *proc;
1288
	LOCKMASK	aheadRequests = 0;
M
 
Marc G. Fournier 已提交
1289

1290
	Assert(queue_size >= 0);
1291

1292 1293
	if (queue_size == 0)
		return;
1294

1295
	proc = (PGPROC *) waitQueue->links.next;
1296

1297 1298
	while (queue_size-- > 0)
	{
B
Bruce Momjian 已提交
1299
		LOCKMODE	lockmode = proc->waitLockMode;
M
 
Marc G. Fournier 已提交
1300 1301

		/*
B
Bruce Momjian 已提交
1302 1303
		 * Waken if (a) doesn't conflict with requests of earlier waiters, and
		 * (b) doesn't conflict with already-held locks.
M
 
Marc G. Fournier 已提交
1304
		 */
B
Bruce Momjian 已提交
1305
		if ((lockMethodTable->conflictTab[lockmode] & aheadRequests) == 0 &&
1306 1307 1308
			LockCheckConflicts(lockMethodTable,
							   lockmode,
							   lock,
1309
							   proc->waitProcLock,
1310
							   proc) == STATUS_OK)
M
 
Marc G. Fournier 已提交
1311
		{
1312
			/* OK to waken */
1313
			GrantLock(lock, proc->waitProcLock, lockmode);
1314
			proc = ProcWakeup(proc, STATUS_OK);
B
Bruce Momjian 已提交
1315

1316
			/*
B
Bruce Momjian 已提交
1317 1318 1319
			 * ProcWakeup removes proc from the lock's waiting process queue
			 * and returns the next proc in chain; don't use proc's next-link,
			 * because it's been cleared.
1320
			 */
M
 
Marc G. Fournier 已提交
1321
		}
1322
		else
1323
		{
B
Bruce Momjian 已提交
1324
			/*
B
Bruce Momjian 已提交
1325
			 * Cannot wake this guy. Remember his request for later checks.
B
Bruce Momjian 已提交
1326
			 */
1327
			aheadRequests |= LOCKBIT_ON(lockmode);
1328
			proc = (PGPROC *) proc->links.next;
1329
		}
M
 
Marc G. Fournier 已提交
1330
	}
1331 1332

	Assert(waitQueue->size >= 0);
1333 1334
}

1335 1336 1337
/*
 * CheckDeadLock
 *
1338
 * We only get to this routine if we got SIGALRM after DeadlockTimeout
1339 1340
 * while waiting for a lock to be released by some other process.  Look
 * to see if there's a deadlock; if not, just return and continue waiting.
1341
 * (But signal ProcSleep to log a message, if log_lock_waits is true.)
1342 1343
 * If we have a real deadlock, remove ourselves from the lock's wait queue
 * and signal an error to ProcSleep.
1344 1345 1346
 *
 * NB: this is run inside a signal handler, so be very wary about what is done
 * here or in called routines.
1347
 */
1348
static void
1349
CheckDeadLock(void)
1350
{
1351 1352
	int			i;

1353
	/*
B
Bruce Momjian 已提交
1354 1355
	 * Acquire exclusive lock on the entire shared lock data structures. Must
	 * grab LWLocks in partition-number order to avoid LWLock deadlock.
1356 1357 1358 1359 1360 1361
	 *
	 * Note that the deadlock check interrupt had better not be enabled
	 * anywhere that this process itself holds lock partition locks, else this
	 * will wait forever.  Also note that LWLockAcquire creates a critical
	 * section, so that this routine cannot be interrupted by cancel/die
	 * interrupts.
1362
	 */
1363 1364
	for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
		LWLockAcquire(FirstLockMgrLock + i, LW_EXCLUSIVE);
1365

1366
	/*
1367 1368
	 * Check to see if we've been awoken by anyone in the interim.
	 *
1369
	 * If we have, we can return and resume our transaction -- happy day.
1370 1371
	 * Before we are awoken the process releasing the lock grants it to us so
	 * we know that we don't have to wait anymore.
1372
	 *
1373
	 * We check by looking to see if we've been unlinked from the wait queue.
B
Bruce Momjian 已提交
1374
	 * This is quicker than checking our semaphore's state, since no kernel
1375
	 * call is needed, and it is safe because we hold the lock partition lock.
1376
	 */
1377 1378
	if (MyProc->links.prev == NULL ||
		MyProc->links.next == NULL)
1379 1380 1381 1382 1383 1384 1385 1386 1387 1388
		goto check_done;

#ifdef LOCK_DEBUG
	if (Debug_deadlocks)
		DumpAllLocks();
#endif

	/* Run the deadlock check, and set deadlock_state for use by ProcSleep */
	deadlock_state = DeadLockCheck(MyProc);

1389
	if (deadlock_state == DS_HARD_DEADLOCK)
B
Bruce Momjian 已提交
1390
	{
1391 1392 1393
		/*
		 * Oops.  We have a deadlock.
		 *
1394 1395 1396 1397
		 * Get this process out of wait state. (Note: we could do this more
		 * efficiently by relying on lockAwaited, but use this coding to
		 * preserve the flexibility to kill some other transaction than the
		 * one detecting the deadlock.)
1398 1399
		 *
		 * RemoveFromWaitQueue sets MyProc->waitStatus to STATUS_ERROR, so
1400 1401
		 * ProcSleep will report an error after we return from the signal
		 * handler.
1402 1403 1404
		 */
		Assert(MyProc->waitLock != NULL);
		RemoveFromWaitQueue(MyProc, LockTagHashCode(&(MyProc->waitLock->tag)));
1405

1406 1407 1408 1409 1410
		/*
		 * Unlock my semaphore so that the interrupted ProcSleep() call can
		 * finish.
		 */
		PGSemaphoreUnlock(&MyProc->sem);
1411

1412
		/*
1413 1414 1415 1416 1417 1418 1419 1420
		 * We're done here.  Transaction abort caused by the error that
		 * ProcSleep will raise will cause any other locks we hold to be
		 * released, thus allowing other processes to wake up; we don't need
		 * to do that here.  NOTE: an exception is that releasing locks we
		 * hold doesn't consider the possibility of waiters that were blocked
		 * behind us on the lock we just failed to get, and might now be
		 * wakable because we're not in front of them anymore.  However,
		 * RemoveFromWaitQueue took care of waking up any such processes.
1421 1422
		 */
	}
1423
	else if (log_lock_waits || deadlock_state == DS_BLOCKED_BY_AUTOVACUUM)
1424 1425 1426 1427
	{
		/*
		 * Unlock my semaphore so that the interrupted ProcSleep() call can
		 * print the log message (we daren't do it here because we are inside
B
Bruce Momjian 已提交
1428 1429
		 * a signal handler).  It will then sleep again until someone releases
		 * the lock.
1430 1431
		 *
		 * If blocked by autovacuum, this wakeup will enable ProcSleep to send
1432
		 * the canceling signal to the autovacuum worker.
1433 1434 1435
		 */
		PGSemaphoreUnlock(&MyProc->sem);
	}
1436 1437

	/*
B
Bruce Momjian 已提交
1438 1439 1440 1441 1442
	 * And release locks.  We do this in reverse order for two reasons: (1)
	 * Anyone else who needs more than one of the locks will be trying to lock
	 * them in increasing order; we don't want to release the other process
	 * until it can get all the locks it needs. (2) This avoids O(N^2)
	 * behavior inside LWLockRelease.
1443
	 */
1444
check_done:
B
Bruce Momjian 已提交
1445
	for (i = NUM_LOCK_PARTITIONS; --i >= 0;)
1446
		LWLockRelease(FirstLockMgrLock + i);
1447 1448 1449
}


1450 1451 1452 1453 1454 1455
/*
 * ProcWaitForSignal - wait for a signal from another backend.
 *
 * This can share the semaphore normally used for waiting for locks,
 * since a backend could never be waiting for a lock and a signal at
 * the same time.  As with locks, it's OK if the signal arrives just
B
Bruce Momjian 已提交
1456
 * before we actually reach the waiting state.	Also as with locks,
1457 1458
 * it's necessary that the caller be robust against bogus wakeups:
 * always check that the desired state has occurred, and wait again
B
Bruce Momjian 已提交
1459
 * if not.	This copes with possible "leftover" wakeups.
1460 1461 1462 1463
 */
void
ProcWaitForSignal(void)
{
1464
	PGSemaphoreLock(&MyProc->sem, true);
1465 1466 1467
}

/*
1468
 * ProcSendSignal - send a signal to a backend identified by PID
1469 1470
 */
void
1471
ProcSendSignal(int pid)
1472
{
1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483
	PGPROC	   *proc = NULL;

	if (RecoveryInProgress())
	{
		/* use volatile pointer to prevent code rearrangement */
		volatile PROC_HDR *procglobal = ProcGlobal;

		SpinLockAcquire(ProcStructLock);

		/*
		 * Check to see whether it is the Startup process we wish to signal.
B
Bruce Momjian 已提交
1484 1485
		 * This call is made by the buffer manager when it wishes to wake up a
		 * process that has been waiting for a pin in so it can obtain a
1486
		 * cleanup lock using LockBufferForCleanup(). Startup is not a normal
B
Bruce Momjian 已提交
1487 1488
		 * backend, so BackendPidGetProc() will not return any pid at all. So
		 * we remember the information for this special case.
1489 1490 1491 1492 1493 1494 1495 1496 1497
		 */
		if (pid == procglobal->startupProcPid)
			proc = procglobal->startupProc;

		SpinLockRelease(ProcStructLock);
	}

	if (proc == NULL)
		proc = BackendPidGetProc(pid);
1498 1499

	if (proc != NULL)
1500
		PGSemaphoreUnlock(&proc->sem);
1501 1502 1503
}


1504 1505 1506 1507 1508 1509 1510 1511 1512
/*****************************************************************************
 * SIGALRM interrupt support
 *
 * Maybe these should be in pqsignal.c?
 *****************************************************************************/

/*
 * Enable the SIGALRM interrupt to fire after the specified delay
 *
1513
 * Delay is given in milliseconds.	Caller should be sure a SIGALRM
1514 1515
 * signal handler is installed before this is called.
 *
1516 1517
 * This code properly handles nesting of deadlock timeout alarms within
 * statement timeout alarms.
1518
 *
1519 1520 1521
 * Returns TRUE if okay, FALSE on failure.
 */
bool
1522
enable_sig_alarm(int delayms, bool is_statement_timeout)
1523
{
1524
	TimestampTz fin_time;
1525
	struct itimerval timeval;
1526

1527 1528
	if (is_statement_timeout)
	{
1529 1530 1531 1532 1533 1534 1535 1536 1537 1538
		/*
		 * Begin statement-level timeout
		 *
		 * Note that we compute statement_fin_time with reference to the
		 * statement_timestamp, but apply the specified delay without any
		 * correction; that is, we ignore whatever time has elapsed since
		 * statement_timestamp was set.  In the normal case only a small
		 * interval will have elapsed and so this doesn't matter, but there
		 * are corner cases (involving multi-statement query strings with
		 * embedded COMMIT or ROLLBACK) where we might re-initialize the
B
Bruce Momjian 已提交
1539 1540 1541 1542
		 * statement timeout long after initial receipt of the message. In
		 * such cases the enforcement of the statement timeout will be a bit
		 * inconsistent.  This annoyance is judged not worth the cost of
		 * performing an additional gettimeofday() here.
1543
		 */
1544
		Assert(!deadlock_timeout_active);
1545 1546
		fin_time = GetCurrentStatementStartTimestamp();
		fin_time = TimestampTzPlusMilliseconds(fin_time, delayms);
1547
		statement_fin_time = fin_time;
1548
		cancel_from_timeout = false;
1549
		statement_timeout_active = true;
1550 1551 1552 1553 1554 1555
	}
	else if (statement_timeout_active)
	{
		/*
		 * Begin deadlock timeout with statement-level timeout active
		 *
1556 1557 1558 1559
		 * 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.
1560 1561 1562
		 *
		 * NOTE: in this case it is possible that this routine will be
		 * interrupted by the previously-set timer alarm.  This is okay
B
Bruce Momjian 已提交
1563 1564 1565
		 * 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.
1566
		 */
1567 1568
		timeout_start_time = GetCurrentTimestamp();
		fin_time = TimestampTzPlusMilliseconds(timeout_start_time, delayms);
1569
		deadlock_timeout_active = true;
1570
		if (fin_time >= statement_fin_time)
1571 1572 1573 1574 1575 1576
			return true;
	}
	else
	{
		/* Begin deadlock timeout with no statement-level timeout */
		deadlock_timeout_active = true;
1577 1578 1579
		/* GetCurrentTimestamp can be expensive, so only do it if we must */
		if (log_lock_waits)
			timeout_start_time = GetCurrentTimestamp();
1580
	}
1581

1582
	/* If we reach here, okay to set the timer interrupt */
1583
	MemSet(&timeval, 0, sizeof(struct itimerval));
1584 1585
	timeval.it_value.tv_sec = delayms / 1000;
	timeval.it_value.tv_usec = (delayms % 1000) * 1000;
1586
	if (setitimer(ITIMER_REAL, &timeval, NULL))
1587
		return false;
1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608
	return true;
}

/*
 * Cancel the SIGALRM timer, either for a deadlock timeout or a statement
 * timeout.  If a deadlock timeout is canceled, any active statement timeout
 * remains in force.
 *
 * Returns TRUE if okay, FALSE on failure.
 */
bool
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)
1609
	{
1610
		struct itimerval timeval;
1611

1612
		MemSet(&timeval, 0, sizeof(struct itimerval));
1613
		if (setitimer(ITIMER_REAL, &timeval, NULL))
1614
		{
1615 1616 1617
			statement_timeout_active = false;
			cancel_from_timeout = false;
			deadlock_timeout_active = false;
1618 1619
			return false;
		}
1620 1621
	}

1622 1623 1624 1625
	/* Always cancel deadlock timeout, in case this is error cleanup */
	deadlock_timeout_active = false;

	/* Cancel or reschedule statement timeout */
1626
	if (is_statement_timeout)
1627
	{
1628
		statement_timeout_active = false;
1629 1630
		cancel_from_timeout = false;
	}
1631 1632 1633 1634 1635
	else if (statement_timeout_active)
	{
		if (!CheckStatementTimeout())
			return false;
	}
1636 1637 1638
	return true;
}

1639

1640
/*
1641 1642 1643
 * 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.
1644
 *
1645
 * Returns true if okay, false if failed to set the interrupt.
1646
 */
1647 1648
static bool
CheckStatementTimeout(void)
1649
{
1650
	TimestampTz now;
B
Bruce Momjian 已提交
1651

1652 1653 1654
	if (!statement_timeout_active)
		return true;			/* do nothing if not active */

1655
	now = GetCurrentTimestamp();
1656

1657
	if (now >= statement_fin_time)
1658
	{
1659 1660
		/* Time to die */
		statement_timeout_active = false;
1661
		cancel_from_timeout = true;
1662 1663 1664 1665
#ifdef HAVE_SETSID
		/* try to signal whole process group */
		kill(-MyProcPid, SIGINT);
#endif
1666
		kill(MyProcPid, SIGINT);
1667 1668 1669 1670
	}
	else
	{
		/* Not time yet, so (re)schedule the interrupt */
1671 1672
		long		secs;
		int			usecs;
1673 1674
		struct itimerval timeval;

1675 1676
		TimestampDifference(now, statement_fin_time,
							&secs, &usecs);
B
Bruce Momjian 已提交
1677

1678 1679 1680 1681 1682 1683
		/*
		 * It's possible that the difference is less than a microsecond;
		 * ensure we don't cancel, rather than set, the interrupt.
		 */
		if (secs == 0 && usecs == 0)
			usecs = 1;
1684
		MemSet(&timeval, 0, sizeof(struct itimerval));
1685 1686
		timeval.it_value.tv_sec = secs;
		timeval.it_value.tv_usec = usecs;
1687
		if (setitimer(ITIMER_REAL, &timeval, NULL))
1688 1689 1690
			return false;
	}

1691 1692
	return true;
}
1693 1694 1695


/*
1696
 * Signal handler for SIGALRM for normal user backends
1697 1698 1699 1700 1701
 *
 * 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.
1702 1703 1704 1705
 */
void
handle_sig_alarm(SIGNAL_ARGS)
{
1706 1707
	int			save_errno = errno;

1708 1709 1710 1711
	/* SIGALRM is cause for waking anything waiting on the process latch */
	if (MyProc)
		SetLatch(&MyProc->procLatch);

1712
	if (deadlock_timeout_active)
1713
	{
1714
		deadlock_timeout_active = false;
1715 1716
		CheckDeadLock();
	}
1717 1718 1719 1720 1721

	if (statement_timeout_active)
		(void) CheckStatementTimeout();

	errno = save_errno;
1722
}
1723 1724 1725 1726 1727 1728 1729

/*
 * Signal handler for SIGALRM in Startup process
 *
 * 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.
1730 1731 1732
 *
 * We set either deadlock_timeout_active or statement_timeout_active
 * or both. Interrupts are enabled if standby_timeout_active.
1733 1734
 */
bool
1735
enable_standby_sig_alarm(TimestampTz now, TimestampTz fin_time, bool deadlock_only)
1736
{
1737 1738
	TimestampTz deadlock_time = TimestampTzPlusMilliseconds(now,
															DeadlockTimeout);
1739

1740 1741 1742
	if (deadlock_only)
	{
		/*
1743
		 * Wake up at deadlock_time only, then wait forever
1744 1745 1746 1747 1748 1749 1750 1751
		 */
		statement_fin_time = deadlock_time;
		deadlock_timeout_active = true;
		statement_timeout_active = false;
	}
	else if (fin_time > deadlock_time)
	{
		/*
1752
		 * Wake up at deadlock_time, then again at fin_time
1753 1754 1755 1756 1757 1758 1759 1760 1761
		 */
		statement_fin_time = deadlock_time;
		statement_fin_time2 = fin_time;
		deadlock_timeout_active = true;
		statement_timeout_active = true;
	}
	else
	{
		/*
1762
		 * Wake only at fin_time because its fairly soon
1763 1764 1765 1766 1767
		 */
		statement_fin_time = fin_time;
		deadlock_timeout_active = false;
		statement_timeout_active = true;
	}
1768

1769 1770 1771 1772 1773
	if (deadlock_timeout_active || statement_timeout_active)
	{
		long		secs;
		int			usecs;
		struct itimerval timeval;
B
Bruce Momjian 已提交
1774

1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785
		TimestampDifference(now, statement_fin_time,
							&secs, &usecs);
		if (secs == 0 && usecs == 0)
			usecs = 1;
		MemSet(&timeval, 0, sizeof(struct itimerval));
		timeval.it_value.tv_sec = secs;
		timeval.it_value.tv_usec = usecs;
		if (setitimer(ITIMER_REAL, &timeval, NULL))
			return false;
		standby_timeout_active = true;
	}
1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825

	return true;
}

bool
disable_standby_sig_alarm(void)
{
	/*
	 * 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 CheckStandbyTimeout.
	 */
	if (standby_timeout_active)
	{
		struct itimerval timeval;

		MemSet(&timeval, 0, sizeof(struct itimerval));
		if (setitimer(ITIMER_REAL, &timeval, NULL))
		{
			standby_timeout_active = false;
			return false;
		}
	}

	standby_timeout_active = false;

	return true;
}

/*
 * CheckStandbyTimeout() runs unconditionally in the Startup process
 * SIGALRM handler. Timers will only be set when InHotStandby.
 * We simply ignore any signals unless the timer has been set.
 */
static bool
CheckStandbyTimeout(void)
{
	TimestampTz now;
B
Bruce Momjian 已提交
1826
	bool		reschedule = false;
1827 1828 1829 1830 1831

	standby_timeout_active = false;

	now = GetCurrentTimestamp();

1832
	/*
B
Bruce Momjian 已提交
1833 1834
	 * Reschedule the timer if its not time to wake yet, or if we have both
	 * timers set and the first one has just been reached.
1835
	 */
1836
	if (now >= statement_fin_time)
1837 1838 1839 1840
	{
		if (deadlock_timeout_active)
		{
			/*
1841
			 * We're still waiting when we reach deadlock timeout, so send out
B
Bruce Momjian 已提交
1842 1843
			 * a request to have other backends check themselves for deadlock.
			 * Then continue waiting until statement_fin_time, if that's set.
1844 1845 1846 1847 1848
			 */
			SendRecoveryConflictWithBufferPin(PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK);
			deadlock_timeout_active = false;

			/*
1849
			 * Begin second waiting period if required.
1850 1851 1852 1853 1854 1855 1856 1857 1858 1859
			 */
			if (statement_timeout_active)
			{
				reschedule = true;
				statement_fin_time = statement_fin_time2;
			}
		}
		else
		{
			/*
1860 1861
			 * We've now reached statement_fin_time, so ask all conflicts to
			 * leave, so we can press ahead with applying changes in recovery.
1862 1863 1864 1865
			 */
			SendRecoveryConflictWithBufferPin(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN);
		}
	}
1866
	else
1867 1868 1869
		reschedule = true;

	if (reschedule)
1870 1871 1872 1873
	{
		long		secs;
		int			usecs;
		struct itimerval timeval;
B
Bruce Momjian 已提交
1874

1875 1876 1877 1878 1879 1880 1881 1882 1883
		TimestampDifference(now, statement_fin_time,
							&secs, &usecs);
		if (secs == 0 && usecs == 0)
			usecs = 1;
		MemSet(&timeval, 0, sizeof(struct itimerval));
		timeval.it_value.tv_sec = secs;
		timeval.it_value.tv_usec = usecs;
		if (setitimer(ITIMER_REAL, &timeval, NULL))
			return false;
1884
		standby_timeout_active = true;
1885 1886 1887 1888 1889 1890 1891 1892
	}

	return true;
}

void
handle_standby_sig_alarm(SIGNAL_ARGS)
{
B
Bruce Momjian 已提交
1893
	int			save_errno = errno;
1894 1895 1896 1897 1898 1899

	if (standby_timeout_active)
		(void) CheckStandbyTimeout();

	errno = save_errno;
}