diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
index da21ef568918..6c9b447c6678 100644
--- a/doc/src/sgml/xfunc.sgml
+++ b/doc/src/sgml/xfunc.sgml
@@ -3668,11 +3668,14 @@ LWLockRelease(AddinShmemInitLock);
shmem_startup_hook provides a convenient place for the
initialization code, but it is not strictly required that all such code
- be placed in this hook. Each backend will execute the registered
- shmem_startup_hook shortly after it attaches to shared
- memory. Note that add-ins should still acquire
+ be placed in this hook. On Windows (and anywhere else where
+ EXEC_BACKEND is defined), each backend executes the
+ registered shmem_startup_hook shortly after it
+ attaches to shared memory, so add-ins should still acquire
AddinShmemInitLock within this hook, as shown in the
- example above.
+ example above. On other platforms, the postmaster process executes the
+ shmem_startup_hook once, and each backend
+ automatically inherits the pointers to shared memory.
diff --git a/src/test/modules/test_slru/test_slru.c b/src/test/modules/test_slru/test_slru.c
index 8c0367eeee42..f41422cca7d4 100644
--- a/src/test/modules/test_slru/test_slru.c
+++ b/src/test/modules/test_slru/test_slru.c
@@ -219,8 +219,8 @@ test_slru_shmem_startup(void)
*/
const bool long_segment_names = true;
const char slru_dir_name[] = "pg_test_slru";
- int test_tranche_id;
- int test_buffer_tranche_id;
+ int test_tranche_id = -1;
+ int test_buffer_tranche_id = -1;
if (prev_shmem_startup_hook)
prev_shmem_startup_hook();
@@ -231,10 +231,19 @@ test_slru_shmem_startup(void)
*/
(void) MakePGDirectory(slru_dir_name);
- /* initialize the SLRU facility */
- test_tranche_id = LWLockNewTrancheId("test_slru_tranche");
-
- test_buffer_tranche_id = LWLockNewTrancheId("test_buffer_tranche");
+ /*
+ * Initialize the SLRU facility.
+ *
+ * In EXEC_BACKEND builds, the shmem_startup_hook is called in the
+ * postmaster and in each backend, but we only need to generate the LWLock
+ * tranches once. Note that these IDs are not used by SimpleLruInit() in
+ * the IsUnderPostmaster (i.e., backend) case.
+ */
+ if (!IsUnderPostmaster)
+ {
+ test_tranche_id = LWLockNewTrancheId("test_slru_tranche");
+ test_buffer_tranche_id = LWLockNewTrancheId("test_buffer_tranche");
+ }
TestSlruCtl->PagePrecedes = test_slru_page_precedes_logically;
SimpleLruInit(TestSlruCtl, "TestSLRU",