@@ -155,9 +155,10 @@ init_dsm_registry(void)
155155{
156156/* Initialize dynamic shared hash table for registry. */
157157dsm_registry_dsa = dsa_create (LWTRANCHE_DSM_REGISTRY_DSA );
158+ dsm_registry_table = dshash_create (dsm_registry_dsa ,& dsh_params ,NULL );
159+
158160dsa_pin (dsm_registry_dsa );
159161dsa_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. */
163164DSMRegistryCtx -> dsah = dsa_get_handle (dsm_registry_dsa );
@@ -188,6 +189,8 @@ GetNamedDSMSegment(const char *name, size_t size,
188189DSMRegistryEntry * entry ;
189190MemoryContext oldcontext ;
190191void * ret ;
192+ NamedDSMState * state ;
193+ dsm_segment * seg ;
191194
192195Assert (found );
193196
@@ -210,36 +213,36 @@ GetNamedDSMSegment(const char *name, size_t size,
210213init_dsm_registry ();
211214
212215entry = dshash_find_or_insert (dsm_registry_table ,name ,found );
216+ state = & entry -> dsm ;
213217if (!(* found ))
214218{
215- NamedDSMState * state = & entry -> dsm ;
216- dsm_segment * seg ;
217-
218219entry -> 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. */
221235seg = dsm_create (size ,0 );
222236
237+ if (init_callback )
238+ (* init_callback ) (dsm_segment_address (seg ));
239+
223240dsm_pin_segment (seg );
224241dsm_pin_mapping (seg );
225242state -> 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" )));
238244else
239245{
240- NamedDSMState * state = & entry -> dsm ;
241- dsm_segment * seg ;
242-
243246/* If the existing segment is not already attached, attach it now. */
244247seg = dsm_find_mapping (state -> handle );
245248if (seg == NULL )
@@ -250,10 +253,9 @@ GetNamedDSMSegment(const char *name, size_t size,
250253
251254dsm_pin_mapping (seg );
252255}
253-
254- ret = dsm_segment_address (seg );
255256}
256257
258+ ret = dsm_segment_address (seg );
257259dshash_release_lock (dsm_registry_table ,entry );
258260MemoryContextSwitchTo (oldcontext );
259261
@@ -274,6 +276,7 @@ GetNamedDSA(const char *name, bool *found)
274276DSMRegistryEntry * entry ;
275277MemoryContext oldcontext ;
276278dsa_area * ret ;
279+ NamedDSAState * state ;
277280
278281Assert (found );
279282
@@ -292,14 +295,28 @@ GetNamedDSA(const char *name, bool *found)
292295init_dsm_registry ();
293296
294297entry = dshash_find_or_insert (dsm_registry_table ,name ,found );
298+ state = & entry -> dsa ;
295299if (!(* found ))
296300{
297- NamedDSAState * state = & entry -> dsa ;
298-
299301entry -> 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. */
302314state -> tranche = LWLockNewTrancheId (name );
315+ }
316+
317+ if (state -> handle == DSA_HANDLE_INVALID )
318+ {
319+ * found = false;
303320
304321/* Initialize the DSA. */
305322ret = dsa_create (state -> tranche );
@@ -309,17 +326,11 @@ GetNamedDSA(const char *name, bool *found)
309326/* Store handle for other backends to use. */
310327state -> handle = dsa_get_handle (ret );
311328}
312- else if (entry -> type != DSMR_ENTRY_TYPE_DSA )
329+ else if (dsa_is_attached ( state -> handle ) )
313330ereport (ERROR ,
314- (errmsg ("requested DSAdoes not match type of existing entry " )));
331+ (errmsg ("requested DSAalready attached to current process " )));
315332else
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. */
324335ret = dsa_attach (state -> handle );
325336dsa_pin_mapping (ret );
@@ -346,6 +357,7 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found)
346357DSMRegistryEntry * entry ;
347358MemoryContext oldcontext ;
348359dshash_table * ret ;
360+ NamedDSHState * dsh_state ;
349361
350362Assert (params );
351363Assert (found );
@@ -365,45 +377,57 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found)
365377init_dsm_registry ();
366378
367379entry = dshash_find_or_insert (dsm_registry_table ,name ,found );
380+ dsh_state = & entry -> dsh ;
368381if (!(* found ))
369382{
370- NamedDSHState * dsh_state = & entry -> dsh ;
371- dshash_parameters params_copy ;
372- dsa_area * dsa ;
373-
374383entry -> 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. */
377397dsh_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. */
380408dsa = dsa_create (dsh_state -> tranche );
381- dsa_pin (dsa );
382- dsa_pin_mapping (dsa );
383409
384410/* Initialize the dshash table. */
385411memcpy (& params_copy ,params ,sizeof (dshash_parameters ));
386412params_copy .tranche_id = dsh_state -> tranche ;
387413ret = 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. */
390419dsh_state -> dsa_handle = dsa_get_handle (dsa );
391420dsh_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 ) )
394423ereport (ERROR ,
395- (errmsg ("requested DSHashdoes not match type of existing entry " )));
424+ (errmsg ("requested DSHashalready attached to current process " )));
396425else
397426{
398- NamedDSHState * dsh_state = & entry -> dsh ;
399427dsa_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. */
408432dsa = dsa_attach (dsh_state -> dsa_handle );
409433dsa_pin_mapping (dsa );
@@ -439,6 +463,17 @@ pg_get_dsm_registry_allocations(PG_FUNCTION_ARGS)
439463Datum vals [3 ];
440464bool 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+
442477vals [0 ]= CStringGetTextDatum (entry -> name );
443478vals [1 ]= CStringGetTextDatum (DSMREntryTypeNames [entry -> type ]);
444479