1
0
mirror of https://github.com/postgres/postgres.git synced 2025-12-18 05:01:01 +03:00

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
This commit is contained in:
Nathan Bossart
2025-12-15 14:27:16 -06:00
parent 64bf53dd61
commit 48d4a1423d
7 changed files with 26 additions and 18 deletions

View File

@@ -858,7 +858,7 @@ autoprewarm_dump_now(PG_FUNCTION_ARGS)
} }
static void static void
apw_init_state(void *ptr) apw_init_state(void *ptr, void *arg)
{ {
AutoPrewarmSharedState *state = (AutoPrewarmSharedState *) ptr; AutoPrewarmSharedState *state = (AutoPrewarmSharedState *) ptr;
@@ -880,7 +880,7 @@ apw_init_shmem(void)
apw_state = GetNamedDSMSegment("autoprewarm", apw_state = GetNamedDSMSegment("autoprewarm",
sizeof(AutoPrewarmSharedState), sizeof(AutoPrewarmSharedState),
apw_init_state, apw_init_state,
&found); &found, NULL);
return found; return found;
} }

View File

@@ -3696,15 +3696,18 @@ LWLockRelease(AddinShmemInitLock);
use the shared memory should obtain a pointer to it by calling: use the shared memory should obtain a pointer to it by calling:
<programlisting> <programlisting>
void *GetNamedDSMSegment(const char *name, size_t size, void *GetNamedDSMSegment(const char *name, size_t size,
void (*init_callback) (void *ptr), void (*init_callback) (void *ptr, void *arg),
bool *found) bool *found, void *arg)
</programlisting> </programlisting>
If a dynamic shared memory segment with the given name does not yet 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 exist, this function will allocate it and initialize it with the provided
<function>init_callback</function> callback function. If the segment has <function>init_callback</function> callback function. If the segment has
already been allocated and initialized by another backend, this function already been allocated and initialized by another backend, this function
simply attaches the existing dynamic shared memory segment to the current 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>
<para> <para>

View File

@@ -180,11 +180,13 @@ init_dsm_registry(void)
* Initialize or attach a named DSM segment. * Initialize or attach a named DSM segment.
* *
* This routine returns the address of the segment. init_callback is called to * 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 * void *
GetNamedDSMSegment(const char *name, size_t size, 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; DSMRegistryEntry *entry;
MemoryContext oldcontext; MemoryContext oldcontext;
@@ -235,7 +237,7 @@ GetNamedDSMSegment(const char *name, size_t size,
seg = dsm_create(size, 0); seg = dsm_create(size, 0);
if (init_callback) if (init_callback)
(*init_callback) (dsm_segment_address(seg)); (*init_callback) (dsm_segment_address(seg), arg);
dsm_pin_segment(seg); dsm_pin_segment(seg);
dsm_pin_mapping(seg); dsm_pin_mapping(seg);

View File

@@ -16,8 +16,8 @@
#include "lib/dshash.h" #include "lib/dshash.h"
extern void *GetNamedDSMSegment(const char *name, size_t size, extern void *GetNamedDSMSegment(const char *name, size_t size,
void (*init_callback) (void *ptr), void (*init_callback) (void *ptr, void *arg),
bool *found); bool *found, void *arg);
extern dsa_area *GetNamedDSA(const char *name, bool *found); extern dsa_area *GetNamedDSA(const char *name, bool *found);
extern dshash_table *GetNamedDSHash(const char *name, extern dshash_table *GetNamedDSHash(const char *name,
const dshash_parameters *params, const dshash_parameters *params,

View File

@@ -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. * when initializing dynamically with a DSM or when loading the module.
*/ */
static void static void
injection_point_init_state(void *ptr) injection_point_init_state(void *ptr, void *arg)
{ {
InjectionPointSharedState *state = (InjectionPointSharedState *) ptr; InjectionPointSharedState *state = (InjectionPointSharedState *) ptr;
@@ -159,7 +159,7 @@ injection_shmem_startup(void)
* First time through, so initialize. This is shared with the dynamic * First time through, so initialize. This is shared with the dynamic
* initialization using a DSM. * initialization using a DSM.
*/ */
injection_point_init_state(inj_state); injection_point_init_state(inj_state, NULL);
} }
LWLockRelease(AddinShmemInitLock); LWLockRelease(AddinShmemInitLock);
@@ -179,7 +179,7 @@ injection_init_shmem(void)
inj_state = GetNamedDSMSegment("injection_points", inj_state = GetNamedDSMSegment("injection_points",
sizeof(InjectionPointSharedState), sizeof(InjectionPointSharedState),
injection_point_init_state, injection_point_init_state,
&found); &found, NULL);
} }
/* /*

View File

@@ -21,7 +21,7 @@
PG_MODULE_MAGIC; PG_MODULE_MAGIC;
static void static void
init_tranche(void *ptr) init_tranche(void *ptr, void *arg)
{ {
int *tranche_id = (int *) ptr; int *tranche_id = (int *) ptr;
@@ -39,7 +39,7 @@ test_dsa_basic(PG_FUNCTION_ARGS)
dsa_pointer p[100]; dsa_pointer p[100];
tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int), tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int),
init_tranche, &found); init_tranche, &found, NULL);
a = dsa_create(*tranche_id); a = dsa_create(*tranche_id);
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
@@ -80,7 +80,7 @@ test_dsa_resowners(PG_FUNCTION_ARGS)
ResourceOwner childowner; ResourceOwner childowner;
tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int), tranche_id = GetNamedDSMSegment("test_dsa", sizeof(int),
init_tranche, &found); init_tranche, &found, NULL);
/* Create DSA in parent resource owner */ /* Create DSA in parent resource owner */
a = dsa_create(*tranche_id); a = dsa_create(*tranche_id);

View File

@@ -44,10 +44,13 @@ static const dshash_parameters dsh_params = {
}; };
static void static void
init_tdr_dsm(void *ptr) init_tdr_dsm(void *ptr, void *arg)
{ {
TestDSMRegistryStruct *dsm = (TestDSMRegistryStruct *) ptr; 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")); LWLockInitialize(&dsm->lck, LWLockNewTrancheId("test_dsm_registry"));
dsm->val = 0; dsm->val = 0;
} }
@@ -60,7 +63,7 @@ tdr_attach_shmem(void)
tdr_dsm = GetNamedDSMSegment("test_dsm_registry_dsm", tdr_dsm = GetNamedDSMSegment("test_dsm_registry_dsm",
sizeof(TestDSMRegistryStruct), sizeof(TestDSMRegistryStruct),
init_tdr_dsm, init_tdr_dsm,
&found); &found, (void *) (intptr_t) 5432);
if (tdr_dsa == NULL) if (tdr_dsa == NULL)
tdr_dsa = GetNamedDSA("test_dsm_registry_dsa", &found); tdr_dsa = GetNamedDSA("test_dsm_registry_dsa", &found);