v2-0001-Pass-name-and-callback-data-to-GetNamedDSMSegment.patch
application/octet-stream
Filename: v2-0001-Pass-name-and-callback-data-to-GetNamedDSMSegment.patch
Type: application/octet-stream
Part: 0
From ed63279c6510b8d37593070df47e7853d20ceb4a Mon Sep 17 00:00:00 2001
From: Zsolt Parragi <zsolt.parragi@percona.com>
Date: Tue, 2 Dec 2025 20:01:33 +0000
Subject: [PATCH v2 1/1] Pass name and callback data to GetNamedDSMSegment init
callback
Modify the signature of GetNamedDSMSegment to pass the segment name
and an additional init_callback_arg to the init_callback function.
This allows the callback to differentiate initialization logic based on
the segment's name and additional context.
Author: zsolt.parragi@percona.com
Reviewed-by: Nathan Bossart <bossartn@amazon.com>
Reviewed-by: Sami Imseih <samimseih@gmail.com>
Discussion: https://postgr.es/m/CAN4CZFMjh8TrT9ZhWgjVTzBDkYZi2a84BnZ8bM%2BfLPuq7Cirzg%40mail.gmail.com
---
contrib/pg_prewarm/autoprewarm.c | 5 +++--
doc/src/sgml/xfunc.sgml | 15 ++++++++++-----
src/backend/storage/ipc/dsm_registry.c | 10 ++++++----
src/include/storage/dsm_registry.h | 3 ++-
.../modules/injection_points/injection_points.c | 5 +++--
src/test/modules/test_dsa/test_dsa.c | 12 ++++++------
.../modules/test_dsm_registry/test_dsm_registry.c | 3 ++-
7 files changed, 32 insertions(+), 21 deletions(-)
diff --git a/contrib/pg_prewarm/autoprewarm.c b/contrib/pg_prewarm/autoprewarm.c
index 5ba1240d51f..2ff24dad167 100644
--- a/contrib/pg_prewarm/autoprewarm.c
+++ b/contrib/pg_prewarm/autoprewarm.c
@@ -858,11 +858,11 @@ autoprewarm_dump_now(PG_FUNCTION_ARGS)
}
static void
-apw_init_state(void *ptr)
+apw_init_state(void *ptr, const char *name, void *arg)
{
AutoPrewarmSharedState *state = (AutoPrewarmSharedState *) ptr;
- LWLockInitialize(&state->lock, LWLockNewTrancheId("autoprewarm"));
+ LWLockInitialize(&state->lock, LWLockNewTrancheId(name));
state->bgworker_pid = InvalidPid;
state->pid_using_dumpfile = InvalidPid;
}
@@ -880,6 +880,7 @@ apw_init_shmem(void)
apw_state = GetNamedDSMSegment("autoprewarm",
sizeof(AutoPrewarmSharedState),
apw_init_state,
+ NULL,
&found);
return found;
diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
index 7c76ab8c349..5a56e653e38 100644
--- a/doc/src/sgml/xfunc.sgml
+++ b/doc/src/sgml/xfunc.sgml
@@ -3696,15 +3696,20 @@ LWLockRelease(AddinShmemInitLock);
use the shared memory should obtain a pointer to it by calling:
<programlisting>
void *GetNamedDSMSegment(const char *name, size_t size,
- void (*init_callback) (void *ptr),
+ void (*init_callback) (void *ptr, const char *name, void *init_callback_arg),
+ void *init_callback_arg,
bool *found)
</programlisting>
If a dynamic shared memory segment with the given name does not yet
exist, this function will allocate it and initialize it with the provided
- <function>init_callback</function> callback function. If the segment has
- already been allocated and initialized by another backend, this function
- simply attaches the existing dynamic shared memory segment to the current
- backend.
+ <function>init_callback</function> callback function. The
+ <parameter>init_callback_arg</parameter> parameter is passed to the callback
+ function, allowing additional context to be provided during initialization.
+ The <parameter>name</parameter> parameter is passed to the callback to uniquely
+ identify the segment, enabling different initialization logic for different segments.
+ If the segment has already been allocated and initialized by another backend,
+ this function simply attaches the existing dynamic shared memory segment to
+ the current backend.
</para>
<para>
diff --git a/src/backend/storage/ipc/dsm_registry.c b/src/backend/storage/ipc/dsm_registry.c
index 66240318e83..53e17e4f86e 100644
--- a/src/backend/storage/ipc/dsm_registry.c
+++ b/src/backend/storage/ipc/dsm_registry.c
@@ -179,12 +179,14 @@ init_dsm_registry(void)
/*
* Initialize or attach a named DSM segment.
*
- * This routine returns the address of the segment. init_callback is called to
- * initialize the segment when it is first created.
+ * This routine returns the address of the segment. The init_callback is used to
+ * initialize the segment when it is first created. An optional callback_arg is
+ * passed to the init_callback to provide additional context during initialization.
*/
void *
GetNamedDSMSegment(const char *name, size_t size,
- void (*init_callback) (void *ptr), bool *found)
+ void (*init_callback) (void *ptr, const char *name, void *init_callback_arg),
+ void *init_callback_arg, bool *found)
{
DSMRegistryEntry *entry;
MemoryContext oldcontext;
@@ -235,7 +237,7 @@ GetNamedDSMSegment(const char *name, size_t size,
seg = dsm_create(size, 0);
if (init_callback)
- (*init_callback) (dsm_segment_address(seg));
+ (*init_callback) (dsm_segment_address(seg), name, init_callback_arg);
dsm_pin_segment(seg);
dsm_pin_mapping(seg);
diff --git a/src/include/storage/dsm_registry.h b/src/include/storage/dsm_registry.h
index 4871ed509eb..6e4bd3e2cb3 100644
--- a/src/include/storage/dsm_registry.h
+++ b/src/include/storage/dsm_registry.h
@@ -16,7 +16,8 @@
#include "lib/dshash.h"
extern void *GetNamedDSMSegment(const char *name, size_t size,
- void (*init_callback) (void *ptr),
+ void (*init_callback) (void *ptr, const char *name, void *init_callback_arg),
+ void *init_callback_arg,
bool *found);
extern dsa_area *GetNamedDSA(const char *name, bool *found);
extern dshash_table *GetNamedDSHash(const char *name,
diff --git a/src/test/modules/injection_points/injection_points.c b/src/test/modules/injection_points/injection_points.c
index 417b61f31c5..e7c8cdddbf2 100644
--- a/src/test/modules/injection_points/injection_points.c
+++ b/src/test/modules/injection_points/injection_points.c
@@ -115,7 +115,7 @@ static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
* when initializing dynamically with a DSM or when loading the module.
*/
static void
-injection_point_init_state(void *ptr)
+injection_point_init_state(void *ptr, const char *name, void *arg)
{
InjectionPointSharedState *state = (InjectionPointSharedState *) ptr;
@@ -159,7 +159,7 @@ injection_shmem_startup(void)
* First time through, so initialize. This is shared with the dynamic
* initialization using a DSM.
*/
- injection_point_init_state(inj_state);
+ injection_point_init_state(inj_state, "injection_points", NULL);
}
LWLockRelease(AddinShmemInitLock);
@@ -179,6 +179,7 @@ injection_init_shmem(void)
inj_state = GetNamedDSMSegment("injection_points",
sizeof(InjectionPointSharedState),
injection_point_init_state,
+ NULL,
&found);
}
diff --git a/src/test/modules/test_dsa/test_dsa.c b/src/test/modules/test_dsa/test_dsa.c
index 21e4ce6a745..b7412c28204 100644
--- a/src/test/modules/test_dsa/test_dsa.c
+++ b/src/test/modules/test_dsa/test_dsa.c
@@ -21,11 +21,11 @@
PG_MODULE_MAGIC;
static void
-init_tranche(void *ptr)
+init_tranche(void *ptr, const char *name, void *arg)
{
int *tranche_id = (int *) ptr;
- *tranche_id = LWLockNewTrancheId("test_dsa");
+ *tranche_id = LWLockNewTrancheId(name);
}
/* Test basic DSA functionality */
@@ -38,8 +38,8 @@ test_dsa_basic(PG_FUNCTION_ARGS)
dsa_area *a;
dsa_pointer p[100];
- tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int),
- init_tranche, &found);
+ tranche_id = GetNamedDSMSegment("test_dsa_basic", sizeof(int),
+ init_tranche, NULL, &found);
a = dsa_create(*tranche_id);
for (int i = 0; i < 100; i++)
@@ -79,8 +79,8 @@ test_dsa_resowners(PG_FUNCTION_ARGS)
ResourceOwner oldowner;
ResourceOwner childowner;
- tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int),
- init_tranche, &found);
+ tranche_id = GetNamedDSMSegment("test_dsa_resowners", sizeof(int),
+ init_tranche, NULL, &found);
/* Create DSA in parent resource owner */
a = dsa_create(*tranche_id);
diff --git a/src/test/modules/test_dsm_registry/test_dsm_registry.c b/src/test/modules/test_dsm_registry/test_dsm_registry.c
index 4cc2ccdac3f..47330b22a7f 100644
--- a/src/test/modules/test_dsm_registry/test_dsm_registry.c
+++ b/src/test/modules/test_dsm_registry/test_dsm_registry.c
@@ -44,7 +44,7 @@ static const dshash_parameters dsh_params = {
};
static void
-init_tdr_dsm(void *ptr)
+init_tdr_dsm(void *ptr, const char *name, void *arg)
{
TestDSMRegistryStruct *dsm = (TestDSMRegistryStruct *) ptr;
@@ -60,6 +60,7 @@ tdr_attach_shmem(void)
tdr_dsm = GetNamedDSMSegment("test_dsm_registry_dsm",
sizeof(TestDSMRegistryStruct),
init_tdr_dsm,
+ NULL,
&found);
if (tdr_dsa == NULL)
--
2.43.0