diff options
| author | Nathan Bossart | 2025-12-15 20:27:16 +0000 |
|---|---|---|
| committer | Nathan Bossart | 2025-12-15 20:27:16 +0000 |
| commit | 48d4a1423d2e92d10077365532d92e059ba2eb2e (patch) | |
| tree | deb5eb18eaef14743bff7889a3f3112cda58d5c6 | |
| parent | 64bf53dd61ea3224020bb340725a4df6a27bc974 (diff) | |
Allow passing a pointer to GetNamedDSMSegment()'s init callback.
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
| -rw-r--r-- | contrib/pg_prewarm/autoprewarm.c | 4 | ||||
| -rw-r--r-- | doc/src/sgml/xfunc.sgml | 9 | ||||
| -rw-r--r-- | src/backend/storage/ipc/dsm_registry.c | 8 | ||||
| -rw-r--r-- | src/include/storage/dsm_registry.h | 4 | ||||
| -rw-r--r-- | src/test/modules/injection_points/injection_points.c | 6 | ||||
| -rw-r--r-- | src/test/modules/test_dsa/test_dsa.c | 6 | ||||
| -rw-r--r-- | src/test/modules/test_dsm_registry/test_dsm_registry.c | 7 |
7 files changed, 26 insertions, 18 deletions
diff --git a/contrib/pg_prewarm/autoprewarm.c b/contrib/pg_prewarm/autoprewarm.c index 5ba1240d51f..a87b046d8be 100644 --- 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 2de3309267d..e9288bd6b5e 100644 --- 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 66240318e83..072f9399969 100644 --- 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 4871ed509eb..c7c6827afec 100644 --- 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 417b61f31c5..25340e8d81b 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, 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 21e4ce6a745..b9c45c0d41c 100644 --- 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 4cc2ccdac3f..3e5f4f3cda1 100644 --- 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); |
