diff options
| author | Andres Freund | 2015-01-14 17:45:22 +0000 |
|---|---|---|
| committer | Andres Freund | 2015-01-14 17:45:22 +0000 |
| commit | 59f71a0d0b56b2df48db4bf1738aece5551f7a47 (patch) | |
| tree | 6023eb572eade66adb21ee0ae84fd6aa33e30ac9 /src/backend/utils | |
| parent | 85a2a8903f7e9151793308d0638621003aded5ae (diff) | |
Add a default local latch for use in signal handlers.
To do so, move InitializeLatchSupport() into the new common process
initialization functions, and add a new global variable MyLatch.
MyLatch is usable as soon InitPostmasterChild() has been called
(i.e. very early during startup). Initially it points to a process
local latch that exists in all processes. InitProcess/InitAuxiliaryProcess
then replaces that local latch with PGPROC->procLatch. During shutdown
the reverse happens.
This is primarily advantageous for two reasons: For one it simplifies
dealing with the shared process latch, especially in signal handlers,
because instead of having to check for MyProc, MyLatch can be used
unconditionally. For another, a later patch that makes FEs/BE
communication use latches, now can rely on the existence of a latch,
even before having gone through InitProcess.
Discussion: [email protected]
Diffstat (limited to 'src/backend/utils')
| -rw-r--r-- | src/backend/utils/adt/misc.c | 4 | ||||
| -rw-r--r-- | src/backend/utils/init/globals.c | 9 | ||||
| -rw-r--r-- | src/backend/utils/init/miscinit.c | 37 | ||||
| -rw-r--r-- | src/backend/utils/misc/timeout.c | 6 |
4 files changed, 50 insertions, 6 deletions
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index ed5a795bb0e..29f7c3badfd 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -413,10 +413,10 @@ pg_sleep(PG_FUNCTION_ARGS) else break; - (void) WaitLatch(&MyProc->procLatch, + (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_TIMEOUT, delay_ms); - ResetLatch(&MyProc->procLatch); + ResetLatch(MyLatch); } PG_RETURN_VOID(); diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c index dc5c8d684a7..c35867bcfe9 100644 --- a/src/backend/utils/init/globals.c +++ b/src/backend/utils/init/globals.c @@ -41,6 +41,15 @@ long MyCancelKey; int MyPMChildSlot; /* + * MyLatch points to the latch that should be used for signal handling by the + * current process. It will either point to a process local latch if the + * current process does not have a PGPROC entry in that moment, or to + * PGPROC->procLatch if it has. Thus it can always be used in signal handlers, + * without checking for its existence. + */ +struct Latch *MyLatch; + +/* * DataDir is the absolute path to the top level of the PGDATA directory tree. * Except during early startup, this is also the server's working directory; * most code therefore can simply use relative paths and not reference DataDir diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 414b05e3b8c..4646e0938e9 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -39,6 +39,7 @@ #include "postmaster/postmaster.h" #include "storage/fd.h" #include "storage/ipc.h" +#include "storage/latch.h" #include "storage/pg_shmem.h" #include "storage/proc.h" #include "storage/procarray.h" @@ -55,6 +56,7 @@ ProcessingMode Mode = InitProcessing; /* List of lock files to be removed at proc exit */ static List *lock_files = NIL; +static Latch LocalLatchData; /* ---------------------------------------------------------------- * ignoring system indexes support stuff @@ -189,6 +191,11 @@ InitPostmasterChild(void) /* We don't want the postmaster's proc_exit() handlers */ on_exit_reset(); + /* Initialize process-local latch support */ + InitializeLatchSupport(); + MyLatch = &LocalLatchData; + InitLatch(MyLatch); + /* * If possible, make this process a group leader, so that the postmaster * can signal any child processes too. Not all processes will have @@ -215,6 +222,11 @@ InitStandaloneProcess(const char *argv0) MyStartTime = time(NULL); /* set our start time in case we call elog */ + /* Initialize process-local latch support */ + InitializeLatchSupport(); + MyLatch = &LocalLatchData; + InitLatch(MyLatch); + /* Compute paths, no postmaster to inherit from */ if (my_exec_path[0] == '\0') { @@ -227,6 +239,31 @@ InitStandaloneProcess(const char *argv0) get_pkglib_path(my_exec_path, pkglib_path); } +void +SwitchToSharedLatch(void) +{ + Assert(MyLatch == &LocalLatchData); + Assert(MyProc != NULL); + + MyLatch = &MyProc->procLatch; + /* + * Set the shared latch as the local one might have been set. This + * shouldn't normally be necessary as code is supposed to check the + * condition before waiting for the latch, but a bit care can't hurt. + */ + SetLatch(MyLatch); +} + +void +SwitchBackToLocalLatch(void) +{ + Assert(MyLatch != &LocalLatchData); + Assert(MyProc != NULL && MyLatch == &MyProc->procLatch); + + MyLatch = &LocalLatchData; + SetLatch(MyLatch); +} + /* * GetUserId - get the current effective user ID. * diff --git a/src/backend/utils/misc/timeout.c b/src/backend/utils/misc/timeout.c index 1dec4928af0..ce4bc13ec3b 100644 --- a/src/backend/utils/misc/timeout.c +++ b/src/backend/utils/misc/timeout.c @@ -284,11 +284,9 @@ handle_sig_alarm(SIGNAL_ARGS) /* * SIGALRM is always cause for waking anything waiting on the process - * latch. Cope with MyProc not being there, as the startup process also - * uses this signal handler. + * latch. */ - if (MyProc) - SetLatch(&MyProc->procLatch); + SetLatch(MyLatch); /* * Fire any pending timeouts, but only if we're enabled to do so. |
