diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c index 228871d2525..98aaee00bfd 100644 --- a/src/backend/storage/ipc/shmem.c +++ b/src/backend/storage/ipc/shmem.c @@ -872,23 +872,29 @@ ShmemAddrIsValid(const void *addr) void RegisterShmemCallbacks(const ShmemCallbacks *callbacks) { - if (shmem_request_state == SRS_DONE && IsUnderPostmaster) + if (shmem_request_state == SRS_DONE) { /* * After-startup initialization or attachment. Call the appropriate * callbacks immediately. + * + * This is not allowed from the postmaster, because the postmaster + * cannot acquire locks. */ if ((callbacks->flags & SHMEM_CALLBACKS_ALLOW_AFTER_STARTUP) == 0) elog(ERROR, "cannot request shared memory at this time"); + Assert(IsUnderPostmaster || !IsPostmasterEnvironment); CallShmemCallbacksAfterStartup(callbacks); } - else + else if (shmem_request_state == SRS_INITIAL) { /* Remember the callbacks for later */ registered_shmem_callbacks = lappend(registered_shmem_callbacks, (void *) callbacks); } + else + elog(ERROR, "cannot request shared memory at this time"); } /* diff --git a/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl b/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl index 5cf07d071ec..546d6a92abe 100644 --- a/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl +++ b/src/test/modules/test_shmem/t/001_late_shmem_alloc.pl @@ -27,6 +27,28 @@ cmp_ok($attach_count2, '>', $attach_count1, "attach callback is called in each backend"); $node->stop; +### +# Test allocating memory after startup in single-user mode +### +SKIP: +{ + # Skip the test on Windows, as single-user mode would fail on permission + # failure with privileged accounts. + skip 'single-user test is not supported by this platform', 1 + if $windows_os; + my $query = "SELECT get_test_shmem_attach_count();\n"; + my $result = run_log( + [ + 'postgres', '--single', '-F', + '-c' => 'exit_on_error=true', + '-D' => $node->data_dir, + 'postgres' + ], + '<' => \$query); + + ok($result, "shmem area is initialized in single-user mode"); +} + ### # Test that loading via shared_preload_libraries also works ###