aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/postmaster/postmaster.c5
-rw-r--r--src/backend/storage/ipc/ipci.c20
-rw-r--r--src/backend/storage/lmgr/lwlock.c18
-rw-r--r--src/backend/utils/init/miscinit.c15
-rw-r--r--src/include/miscadmin.h5
-rw-r--r--src/tools/pgindent/typedefs.list1
6 files changed, 37 insertions, 27 deletions
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index bf591f048d4..3b73e269564 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -1043,6 +1043,11 @@ PostmasterMain(int argc, char *argv[])
InitializeMaxBackends();
/*
+ * Give preloaded libraries a chance to request additional shared memory.
+ */
+ process_shmem_requests();
+
+ /*
* Now that loadable modules have had their chance to request additional
* shared memory, determine the value of any runtime-computed GUCs that
* depend on the amount of shared memory required.
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index 75e456360be..26372d95b38 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -55,25 +55,21 @@ int shared_memory_type = DEFAULT_SHARED_MEMORY_TYPE;
shmem_startup_hook_type shmem_startup_hook = NULL;
static Size total_addin_request = 0;
-static bool addin_request_allowed = true;
-
/*
* RequestAddinShmemSpace
* Request that extra shmem space be allocated for use by
* a loadable module.
*
- * This is only useful if called from the _PG_init hook of a library that
- * is loaded into the postmaster via shared_preload_libraries. Once
- * shared memory has been allocated, calls will be ignored. (We could
- * raise an error, but it seems better to make it a no-op, so that
- * libraries containing such calls can be reloaded if needed.)
+ * This may only be called via the shmem_request_hook of a library that is
+ * loaded into the postmaster via shared_preload_libraries. Calls from
+ * elsewhere will fail.
*/
void
RequestAddinShmemSpace(Size size)
{
- if (IsUnderPostmaster || !addin_request_allowed)
- return; /* too late */
+ if (!process_shmem_requests_in_progress)
+ elog(FATAL, "cannot request additional shared memory outside shmem_request_hook");
total_addin_request = add_size(total_addin_request, size);
}
@@ -83,9 +79,6 @@ RequestAddinShmemSpace(Size size)
*
* If num_semaphores is not NULL, it will be set to the number of semaphores
* required.
- *
- * Note that this function freezes the additional shared memory request size
- * from loadable modules.
*/
Size
CalculateShmemSize(int *num_semaphores)
@@ -152,8 +145,7 @@ CalculateShmemSize(int *num_semaphores)
size = add_size(size, ShmemBackendArraySize());
#endif
- /* freeze the addin request size and include it */
- addin_request_allowed = false;
+ /* include additional requested shmem from preload libraries */
size = add_size(size, total_addin_request);
/* might as well round it off to a multiple of a typical page size */
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index fef462b1102..8aef909037d 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -243,8 +243,6 @@ int NamedLWLockTrancheRequests = 0;
/* points to data in shared memory: */
NamedLWLockTranche *NamedLWLockTrancheArray = NULL;
-static bool lock_named_request_allowed = true;
-
static void InitializeLWLocks(void);
static inline void LWLockReportWaitStart(LWLock *lock);
static inline void LWLockReportWaitEnd(void);
@@ -458,9 +456,6 @@ LWLockShmemSize(void)
for (i = 0; i < NamedLWLockTrancheRequests; i++)
size = add_size(size, strlen(NamedLWLockTrancheRequestArray[i].tranche_name) + 1);
- /* Disallow adding any more named tranches. */
- lock_named_request_allowed = false;
-
return size;
}
@@ -691,12 +686,9 @@ LWLockRegisterTranche(int tranche_id, const char *tranche_name)
* Request that extra LWLocks be allocated during postmaster
* startup.
*
- * This is only useful for extensions if called from the _PG_init hook
- * of a library that is loaded into the postmaster via
- * shared_preload_libraries. Once shared memory has been allocated, calls
- * will be ignored. (We could raise an error, but it seems better to make
- * it a no-op, so that libraries containing such calls can be reloaded if
- * needed.)
+ * This may only be called via the shmem_request_hook of a library that is
+ * loaded into the postmaster via shared_preload_libraries. Calls from
+ * elsewhere will fail.
*
* The tranche name will be user-visible as a wait event name, so try to
* use a name that fits the style for those.
@@ -706,8 +698,8 @@ RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks)
{
NamedLWLockTrancheRequest *request;
- if (IsUnderPostmaster || !lock_named_request_allowed)
- return; /* too late */
+ if (!process_shmem_requests_in_progress)
+ elog(FATAL, "cannot request additional LWLocks outside shmem_request_hook");
if (NamedLWLockTrancheRequestArray == NULL)
{
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 6ed584e1143..ec6a61594a4 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -1618,6 +1618,9 @@ char *local_preload_libraries_string = NULL;
bool process_shared_preload_libraries_in_progress = false;
bool process_shared_preload_libraries_done = false;
+shmem_request_hook_type shmem_request_hook = NULL;
+bool process_shmem_requests_in_progress = false;
+
/*
* load the shared libraries listed in 'libraries'
*
@@ -1701,6 +1704,18 @@ process_session_preload_libraries(void)
true);
}
+/*
+ * process any shared memory requests from preloaded libraries
+ */
+void
+process_shmem_requests(void)
+{
+ process_shmem_requests_in_progress = true;
+ if (shmem_request_hook)
+ shmem_request_hook();
+ process_shmem_requests_in_progress = false;
+}
+
void
pg_bindtextdomain(const char *domain)
{
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 53fd168d93c..0af130fbc5d 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -465,6 +465,7 @@ extern void BaseInit(void);
extern PGDLLIMPORT bool IgnoreSystemIndexes;
extern PGDLLIMPORT bool process_shared_preload_libraries_in_progress;
extern PGDLLIMPORT bool process_shared_preload_libraries_done;
+extern PGDLLIMPORT bool process_shmem_requests_in_progress;
extern PGDLLIMPORT char *session_preload_libraries_string;
extern PGDLLIMPORT char *shared_preload_libraries_string;
extern PGDLLIMPORT char *local_preload_libraries_string;
@@ -478,9 +479,13 @@ extern bool RecheckDataDirLockFile(void);
extern void ValidatePgVersion(const char *path);
extern void process_shared_preload_libraries(void);
extern void process_session_preload_libraries(void);
+extern void process_shmem_requests(void);
extern void pg_bindtextdomain(const char *domain);
extern bool has_rolreplication(Oid roleid);
+typedef void (*shmem_request_hook_type) (void);
+extern PGDLLIMPORT shmem_request_hook_type shmem_request_hook;
+
/* in executor/nodeHash.c */
extern size_t get_hash_memory_limit(void);
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index dd1214977a8..4fb746930aa 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -3651,6 +3651,7 @@ shm_mq_result
shm_toc
shm_toc_entry
shm_toc_estimator
+shmem_request_hook_type
shmem_startup_hook_type
sig_atomic_t
sigjmp_buf