summaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
authorAndres Freund2015-01-14 17:45:22 +0000
committerAndres Freund2015-01-14 17:45:22 +0000
commit59f71a0d0b56b2df48db4bf1738aece5551f7a47 (patch)
tree6023eb572eade66adb21ee0ae84fd6aa33e30ac9 /src/backend/utils
parent85a2a8903f7e9151793308d0638621003aded5ae (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.c4
-rw-r--r--src/backend/utils/init/globals.c9
-rw-r--r--src/backend/utils/init/miscinit.c37
-rw-r--r--src/backend/utils/misc/timeout.c6
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.