@@ -155,9 +155,10 @@ init_dsm_registry(void)
155155 {
156156 /* Initialize dynamic shared hash table for registry. */
157157 dsm_registry_dsa = dsa_create (LWTRANCHE_DSM_REGISTRY_DSA );
158+ dsm_registry_table = dshash_create (dsm_registry_dsa , & dsh_params , NULL );
159+
158160 dsa_pin (dsm_registry_dsa );
159161 dsa_pin_mapping (dsm_registry_dsa );
160- dsm_registry_table = dshash_create (dsm_registry_dsa , & dsh_params , NULL );
161162
162163 /* Store handles in shared memory for other backends to use. */
163164 DSMRegistryCtx -> dsah = dsa_get_handle (dsm_registry_dsa );
@@ -188,6 +189,8 @@ GetNamedDSMSegment(const char *name, size_t size,
188189 DSMRegistryEntry * entry ;
189190 MemoryContext oldcontext ;
190191 void * ret ;
192+ NamedDSMState * state ;
193+ dsm_segment * seg ;
191194
192195 Assert (found );
193196
@@ -210,36 +213,36 @@ GetNamedDSMSegment(const char *name, size_t size,
210213 init_dsm_registry ();
211214
212215 entry = dshash_find_or_insert (dsm_registry_table , name , found );
216+ state = & entry -> dsm ;
213217 if (!(* found ))
214218 {
215- NamedDSMState * state = & entry -> dsm ;
216- dsm_segment * seg ;
217-
218219 entry -> type = DSMR_ENTRY_TYPE_DSM ;
220+ state -> handle = DSM_HANDLE_INVALID ;
221+ state -> size = size ;
222+ }
223+ else if (entry -> type != DSMR_ENTRY_TYPE_DSM )
224+ ereport (ERROR ,
225+ (errmsg ("requested DSM segment does not match type of existing entry" )));
226+ else if (state -> size != size )
227+ ereport (ERROR ,
228+ (errmsg ("requested DSM segment size does not match size of existing segment" )));
229+
230+ if (state -> handle == DSM_HANDLE_INVALID )
231+ {
232+ * found = false;
219233
220234 /* Initialize the segment. */
221235 seg = dsm_create (size , 0 );
222236
237+ if (init_callback )
238+ (* init_callback ) (dsm_segment_address (seg ));
239+
223240 dsm_pin_segment (seg );
224241 dsm_pin_mapping (seg );
225242 state -> handle = dsm_segment_handle (seg );
226- state -> size = size ;
227- ret = dsm_segment_address (seg );
228-
229- if (init_callback )
230- (* init_callback ) (ret );
231243 }
232- else if (entry -> type != DSMR_ENTRY_TYPE_DSM )
233- ereport (ERROR ,
234- (errmsg ("requested DSM segment does not match type of existing entry" )));
235- else if (entry -> dsm .size != size )
236- ereport (ERROR ,
237- (errmsg ("requested DSM segment size does not match size of existing segment" )));
238244 else
239245 {
240- NamedDSMState * state = & entry -> dsm ;
241- dsm_segment * seg ;
242-
243246 /* If the existing segment is not already attached, attach it now. */
244247 seg = dsm_find_mapping (state -> handle );
245248 if (seg == NULL )
@@ -250,10 +253,9 @@ GetNamedDSMSegment(const char *name, size_t size,
250253
251254 dsm_pin_mapping (seg );
252255 }
253-
254- ret = dsm_segment_address (seg );
255256 }
256257
258+ ret = dsm_segment_address (seg );
257259 dshash_release_lock (dsm_registry_table , entry );
258260 MemoryContextSwitchTo (oldcontext );
259261
@@ -274,6 +276,7 @@ GetNamedDSA(const char *name, bool *found)
274276 DSMRegistryEntry * entry ;
275277 MemoryContext oldcontext ;
276278 dsa_area * ret ;
279+ NamedDSAState * state ;
277280
278281 Assert (found );
279282
@@ -292,14 +295,28 @@ GetNamedDSA(const char *name, bool *found)
292295 init_dsm_registry ();
293296
294297 entry = dshash_find_or_insert (dsm_registry_table , name , found );
298+ state = & entry -> dsa ;
295299 if (!(* found ))
296300 {
297- NamedDSAState * state = & entry -> dsa ;
298-
299301 entry -> type = DSMR_ENTRY_TYPE_DSA ;
302+ state -> handle = DSA_HANDLE_INVALID ;
303+ state -> tranche = -1 ;
304+ }
305+ else if (entry -> type != DSMR_ENTRY_TYPE_DSA )
306+ ereport (ERROR ,
307+ (errmsg ("requested DSA does not match type of existing entry" )));
308+
309+ if (state -> tranche == -1 )
310+ {
311+ * found = false;
300312
301313 /* Initialize the LWLock tranche for the DSA. */
302314 state -> tranche = LWLockNewTrancheId (name );
315+ }
316+
317+ if (state -> handle == DSA_HANDLE_INVALID )
318+ {
319+ * found = false;
303320
304321 /* Initialize the DSA. */
305322 ret = dsa_create (state -> tranche );
@@ -309,17 +326,11 @@ GetNamedDSA(const char *name, bool *found)
309326 /* Store handle for other backends to use. */
310327 state -> handle = dsa_get_handle (ret );
311328 }
312- else if (entry -> type != DSMR_ENTRY_TYPE_DSA )
329+ else if (dsa_is_attached ( state -> handle ) )
313330 ereport (ERROR ,
314- (errmsg ("requested DSA does not match type of existing entry " )));
331+ (errmsg ("requested DSA already attached to current process " )));
315332 else
316333 {
317- NamedDSAState * state = & entry -> dsa ;
318-
319- if (dsa_is_attached (state -> handle ))
320- ereport (ERROR ,
321- (errmsg ("requested DSA already attached to current process" )));
322-
323334 /* Attach to existing DSA. */
324335 ret = dsa_attach (state -> handle );
325336 dsa_pin_mapping (ret );
@@ -346,6 +357,7 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found)
346357 DSMRegistryEntry * entry ;
347358 MemoryContext oldcontext ;
348359 dshash_table * ret ;
360+ NamedDSHState * dsh_state ;
349361
350362 Assert (params );
351363 Assert (found );
@@ -365,45 +377,57 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found)
365377 init_dsm_registry ();
366378
367379 entry = dshash_find_or_insert (dsm_registry_table , name , found );
380+ dsh_state = & entry -> dsh ;
368381 if (!(* found ))
369382 {
370- NamedDSHState * dsh_state = & entry -> dsh ;
371- dshash_parameters params_copy ;
372- dsa_area * dsa ;
373-
374383 entry -> type = DSMR_ENTRY_TYPE_DSH ;
384+ dsh_state -> dsa_handle = DSA_HANDLE_INVALID ;
385+ dsh_state -> dsh_handle = DSHASH_HANDLE_INVALID ;
386+ dsh_state -> tranche = -1 ;
387+ }
388+ else if (entry -> type != DSMR_ENTRY_TYPE_DSH )
389+ ereport (ERROR ,
390+ (errmsg ("requested DSHash does not match type of existing entry" )));
391+
392+ if (dsh_state -> tranche == -1 )
393+ {
394+ * found = false;
375395
376396 /* Initialize the LWLock tranche for the hash table. */
377397 dsh_state -> tranche = LWLockNewTrancheId (name );
398+ }
399+
400+ if (dsh_state -> dsa_handle == DSA_HANDLE_INVALID )
401+ {
402+ dshash_parameters params_copy ;
403+ dsa_area * dsa ;
404+
405+ * found = false;
378406
379407 /* Initialize the DSA for the hash table. */
380408 dsa = dsa_create (dsh_state -> tranche );
381- dsa_pin (dsa );
382- dsa_pin_mapping (dsa );
383409
384410 /* Initialize the dshash table. */
385411 memcpy (& params_copy , params , sizeof (dshash_parameters ));
386412 params_copy .tranche_id = dsh_state -> tranche ;
387413 ret = dshash_create (dsa , & params_copy , NULL );
388414
415+ dsa_pin (dsa );
416+ dsa_pin_mapping (dsa );
417+
389418 /* Store handles for other backends to use. */
390419 dsh_state -> dsa_handle = dsa_get_handle (dsa );
391420 dsh_state -> dsh_handle = dshash_get_hash_table_handle (ret );
392421 }
393- else if (entry -> type != DSMR_ENTRY_TYPE_DSH )
422+ else if (dsa_is_attached ( dsh_state -> dsa_handle ) )
394423 ereport (ERROR ,
395- (errmsg ("requested DSHash does not match type of existing entry " )));
424+ (errmsg ("requested DSHash already attached to current process " )));
396425 else
397426 {
398- NamedDSHState * dsh_state = & entry -> dsh ;
399427 dsa_area * dsa ;
400428
401429 /* XXX: Should we verify params matches what table was created with? */
402430
403- if (dsa_is_attached (dsh_state -> dsa_handle ))
404- ereport (ERROR ,
405- (errmsg ("requested DSHash already attached to current process" )));
406-
407431 /* Attach to existing DSA for the hash table. */
408432 dsa = dsa_attach (dsh_state -> dsa_handle );
409433 dsa_pin_mapping (dsa );
@@ -439,6 +463,17 @@ pg_get_dsm_registry_allocations(PG_FUNCTION_ARGS)
439463 Datum vals [3 ];
440464 bool nulls [3 ] = {0 };
441465
466+ /* Do not show partially-initialized entries. */
467+ if (entry -> type == DSMR_ENTRY_TYPE_DSM &&
468+ entry -> dsm .handle == DSM_HANDLE_INVALID )
469+ continue ;
470+ if (entry -> type == DSMR_ENTRY_TYPE_DSA &&
471+ entry -> dsa .handle == DSA_HANDLE_INVALID )
472+ continue ;
473+ if (entry -> type == DSMR_ENTRY_TYPE_DSH &&
474+ entry -> dsh .dsa_handle == DSA_HANDLE_INVALID )
475+ continue ;
476+
442477 vals [0 ] = CStringGetTextDatum (entry -> name );
443478 vals [1 ] = CStringGetTextDatum (DSMREntryTypeNames [entry -> type ]);
444479
0 commit comments