From 3529f2e17b85537198d8a6fa783ca9c0b0522547 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Mon, 24 Nov 2025 12:28:23 -0600 Subject: [PATCH v2 2/2] handle ERRORs in DSM registry functions --- src/backend/storage/ipc/dsm_registry.c | 85 +++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 10 deletions(-) diff --git a/src/backend/storage/ipc/dsm_registry.c b/src/backend/storage/ipc/dsm_registry.c index a926b9c3f32..bae67d15add 100644 --- a/src/backend/storage/ipc/dsm_registry.c +++ b/src/backend/storage/ipc/dsm_registry.c @@ -155,9 +155,10 @@ init_dsm_registry(void) { /* Initialize dynamic shared hash table for registry. */ dsm_registry_dsa = dsa_create(LWTRANCHE_DSM_REGISTRY_DSA); + dsm_registry_table = dshash_create(dsm_registry_dsa, &dsh_params, NULL); + dsa_pin(dsm_registry_dsa); dsa_pin_mapping(dsm_registry_dsa); - dsm_registry_table = dshash_create(dsm_registry_dsa, &dsh_params, NULL); /* Store handles in shared memory for other backends to use. */ DSMRegistryCtx->dsah = dsa_get_handle(dsm_registry_dsa); @@ -218,16 +219,24 @@ GetNamedDSMSegment(const char *name, size_t size, entry->type = DSMR_ENTRY_TYPE_DSM; /* Initialize the segment. */ - seg = dsm_create(size, 0); + PG_TRY(); + { + seg = dsm_create(size, 0); + ret = dsm_segment_address(seg); + if (init_callback) + (*init_callback) (ret); + } + PG_CATCH(); + { + dshash_delete_entry(dsm_registry_table, entry); + PG_RE_THROW(); + } + PG_END_TRY(); dsm_pin_segment(seg); dsm_pin_mapping(seg); state->handle = dsm_segment_handle(seg); state->size = size; - ret = dsm_segment_address(seg); - - if (init_callback) - (*init_callback) (ret); } else if (entry->type != DSMR_ENTRY_TYPE_DSM) ereport(ERROR, @@ -297,12 +306,23 @@ GetNamedDSA(const char *name, bool *found) NamedDSAState *state = &entry->dsa; entry->type = DSMR_ENTRY_TYPE_DSA; + state->handle = DSA_HANDLE_INVALID; /* Initialize the LWLock tranche for the DSA. */ - state->tranche = LWLockNewTrancheId(name); + PG_TRY(); + { + state->tranche = LWLockNewTrancheId(name); + } + PG_CATCH(); + { + dshash_delete_entry(dsm_registry_table, entry); + PG_RE_THROW(); + } + PG_END_TRY(); /* Initialize the DSA. */ ret = dsa_create(state->tranche); + dsa_pin(ret); dsa_pin_mapping(ret); @@ -312,6 +332,19 @@ GetNamedDSA(const char *name, bool *found) else if (entry->type != DSMR_ENTRY_TYPE_DSA) ereport(ERROR, (errmsg("requested DSA does not match type of existing entry"))); + else if (entry->dsa.handle == DSA_HANDLE_INVALID) + { + NamedDSAState *state = &entry->dsa; + + /* Initialize the DSA. */ + ret = dsa_create(state->tranche); + + dsa_pin(ret); + dsa_pin_mapping(ret); + + /* Store handle for other backends to use. */ + state->handle = dsa_get_handle(ret); + } else { NamedDSAState *state = &entry->dsa; @@ -372,20 +405,31 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found) dsa_area *dsa; entry->type = DSMR_ENTRY_TYPE_DSH; + dsh_state->dsa_handle = DSA_HANDLE_INVALID; /* Initialize the LWLock tranche for the hash table. */ - dsh_state->tranche = LWLockNewTrancheId(name); + PG_TRY(); + { + dsh_state->tranche = LWLockNewTrancheId(name); + } + PG_CATCH(); + { + dshash_delete_entry(dsm_registry_table, entry); + PG_RE_THROW(); + } + PG_END_TRY(); /* Initialize the DSA for the hash table. */ dsa = dsa_create(dsh_state->tranche); - dsa_pin(dsa); - dsa_pin_mapping(dsa); /* Initialize the dshash table. */ memcpy(¶ms_copy, params, sizeof(dshash_parameters)); params_copy.tranche_id = dsh_state->tranche; ret = dshash_create(dsa, ¶ms_copy, NULL); + dsa_pin(dsa); + dsa_pin_mapping(dsa); + /* Store handles for other backends to use. */ dsh_state->dsa_handle = dsa_get_handle(dsa); dsh_state->dsh_handle = dshash_get_hash_table_handle(ret); @@ -393,6 +437,27 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found) else if (entry->type != DSMR_ENTRY_TYPE_DSH) ereport(ERROR, (errmsg("requested DSHash does not match type of existing entry"))); + else if (entry->dsh.dsa_handle == DSA_HANDLE_INVALID) + { + NamedDSHState *dsh_state = &entry->dsh; + dshash_parameters params_copy; + dsa_area *dsa; + + /* Initialize the DSA for the hash table. */ + dsa = dsa_create(dsh_state->tranche); + + /* Initialize the dshash table. */ + memcpy(¶ms_copy, params, sizeof(dshash_parameters)); + params_copy.tranche_id = dsh_state->tranche; + ret = dshash_create(dsa, ¶ms_copy, NULL); + + dsa_pin(dsa); + dsa_pin_mapping(dsa); + + /* Store handles for other backends to use. */ + dsh_state->dsa_handle = dsa_get_handle(dsa); + dsh_state->dsh_handle = dshash_get_hash_table_handle(ret); + } else { NamedDSHState *dsh_state = &entry->dsh; -- 2.39.5 (Apple Git-154)