git.postgresql.org Git - postgresql.git/commitdiff

git projects / postgresql.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 64bf53d)
Allow passing a pointer to GetNamedDSMSegment()'s init callback.
2025年12月15日 20:27:16 +0000 (14:27 -0600)
2025年12月15日 20:27:16 +0000 (14:27 -0600)
This commit adds a new "void *arg" parameter to
GetNamedDSMSegment() that is passed to the initialization callback
function. This is useful for reusing an initialization callback
function for multiple DSM segments.

Author: Zsolt Parragi <zsolt.parragi@percona.com>
Reviewed-by: Sami Imseih <samimseih@gmail.com>
Discussion: https://postgr.es/m/CAN4CZFMjh8TrT9ZhWgjVTzBDkYZi2a84BnZ8bM%2BfLPuq7Cirzg%40mail.gmail.com


diff --git a/contrib/pg_prewarm/autoprewarm.c b/contrib/pg_prewarm/autoprewarm.c
index 5ba1240d51f81af911b9d1e5bba5f4f86de1505b..a87b046d8be979f37755fa654eaded1721165a19 100644 (file)
--- a/contrib/pg_prewarm/autoprewarm.c
+++ b/contrib/pg_prewarm/autoprewarm.c
@@ -858,7 +858,7 @@ autoprewarm_dump_now(PG_FUNCTION_ARGS)
}
static void
-apw_init_state(void *ptr)
+apw_init_state(void *ptr, void *arg)
{
AutoPrewarmSharedState *state = (AutoPrewarmSharedState *) ptr;
@@ -880,7 +880,7 @@ apw_init_shmem(void)
apw_state = GetNamedDSMSegment("autoprewarm",
sizeof(AutoPrewarmSharedState),
apw_init_state,
- &found);
+ &found, NULL);
return found;
}
diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
index 2de3309267d40e9349650c3ed8dde8583e5a7387..e9288bd6b5e201ae017ece9360bd417d56b44a4c 100644 (file)
--- a/doc/src/sgml/xfunc.sgml
+++ b/doc/src/sgml/xfunc.sgml
@@ -3696,15 +3696,18 @@ 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),
- bool *found)
+ void (*init_callback) (void *ptr, void *arg),
+ bool *found, void *arg)
</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.
+ backend. In the former case, <function>GetNamedDSMSegment</function>
+ passes the <literal>void *arg</literal> argument to the
+ <function>init_callback</function>. This is particularly useful for
+ reusing an initialization callback function for multiple DSM segments.
</para>
<para>
diff --git a/src/backend/storage/ipc/dsm_registry.c b/src/backend/storage/ipc/dsm_registry.c
index 66240318e83dd0c50f2ffd0afd431c511233a8c9..072f9399969d037a804ab51dd0ae21ad79b1ab15 100644 (file)
--- a/src/backend/storage/ipc/dsm_registry.c
+++ b/src/backend/storage/ipc/dsm_registry.c
@@ -180,11 +180,13 @@ 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.
+ * initialize the segment when it is first created. 'arg' is passed through to
+ * the initialization callback function.
*/
void *
GetNamedDSMSegment(const char *name, size_t size,
- void (*init_callback) (void *ptr), bool *found)
+ void (*init_callback) (void *ptr, void *arg),
+ bool *found, void *arg)
{
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), 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 4871ed509ebc6a03b19e296f6ba029765f1ec3cf..c7c6827afec711a9a85436ae212ef6044dcee642 100644 (file)
--- a/src/include/storage/dsm_registry.h
+++ b/src/include/storage/dsm_registry.h
@@ -16,8 +16,8 @@
#include "lib/dshash.h"
extern void *GetNamedDSMSegment(const char *name, size_t size,
- void (*init_callback) (void *ptr),
- bool *found);
+ void (*init_callback) (void *ptr, void *arg),
+ bool *found, void *arg);
extern dsa_area *GetNamedDSA(const char *name, bool *found);
extern dshash_table *GetNamedDSHash(const char *name,
const dshash_parameters *params,
diff --git a/src/test/modules/injection_points/injection_points.c b/src/test/modules/injection_points/injection_points.c
index 417b61f31c519067403523d986ba2cc2f93ccd3f..25340e8d81be7fb1a1b469967b0efc1fac0ab7f3 100644 (file)
--- 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, 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, NULL);
}
LWLockRelease(AddinShmemInitLock);
@@ -179,7 +179,7 @@ injection_init_shmem(void)
inj_state = GetNamedDSMSegment("injection_points",
sizeof(InjectionPointSharedState),
injection_point_init_state,
- &found);
+ &found, NULL);
}
/*
diff --git a/src/test/modules/test_dsa/test_dsa.c b/src/test/modules/test_dsa/test_dsa.c
index 21e4ce6a74528f0b104c9232c8894f1d81301bc1..b9c45c0d41cfe77879760e14eb1a4cd058e68755 100644 (file)
--- a/src/test/modules/test_dsa/test_dsa.c
+++ b/src/test/modules/test_dsa/test_dsa.c
@@ -21,7 +21,7 @@
PG_MODULE_MAGIC;
static void
-init_tranche(void *ptr)
+init_tranche(void *ptr, void *arg)
{
int *tranche_id = (int *) ptr;
@@ -39,7 +39,7 @@ test_dsa_basic(PG_FUNCTION_ARGS)
dsa_pointer p[100];
tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int),
- init_tranche, &found);
+ init_tranche, &found, NULL);
a = dsa_create(*tranche_id);
for (int i = 0; i < 100; i++)
@@ -80,7 +80,7 @@ test_dsa_resowners(PG_FUNCTION_ARGS)
ResourceOwner childowner;
tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int),
- init_tranche, &found);
+ init_tranche, &found, NULL);
/* 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 4cc2ccdac3f1123ee57afad5008b7be88047d91c..3e5f4f3cda1c063feb47673c3fd930485790d0c2 100644 (file)
--- a/src/test/modules/test_dsm_registry/test_dsm_registry.c
+++ b/src/test/modules/test_dsm_registry/test_dsm_registry.c
@@ -44,10 +44,13 @@ static const dshash_parameters dsh_params = {
};
static void
-init_tdr_dsm(void *ptr)
+init_tdr_dsm(void *ptr, void *arg)
{
TestDSMRegistryStruct *dsm = (TestDSMRegistryStruct *) ptr;
+ if ((int) (intptr_t) arg != 5432)
+ elog(ERROR, "unexpected arg value %d", (int) (intptr_t) arg);
+
LWLockInitialize(&dsm->lck, LWLockNewTrancheId("test_dsm_registry"));
dsm->val = 0;
}
@@ -60,7 +63,7 @@ tdr_attach_shmem(void)
tdr_dsm = GetNamedDSMSegment("test_dsm_registry_dsm",
sizeof(TestDSMRegistryStruct),
init_tdr_dsm,
- &found);
+ &found, (void *) (intptr_t) 5432);
if (tdr_dsa == NULL)
tdr_dsa = GetNamedDSA("test_dsm_registry_dsa", &found);
This is the main PostgreSQL git repository.
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /