>From 719f7e2493832564c58c3ab319344f31abef1653 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Tue, 6 May 2014 19:42:36 +0200
Subject: [PATCH 1/2] Associate names to created dynamic shared memory
 segments.

This unfortunately implies an API breakage.
---
 src/backend/access/transam/parallel.c |  3 +-
 src/backend/storage/ipc/dsm.c         | 61 ++++++++++++++++++++++-------------
 src/include/storage/dsm.h             |  2 +-
 src/test/modules/test_shm_mq/setup.c  |  2 +-
 4 files changed, 42 insertions(+), 26 deletions(-)

diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c
index 0bba9a7..c1473c1 100644
--- a/src/backend/access/transam/parallel.c
+++ b/src/backend/access/transam/parallel.c
@@ -268,7 +268,8 @@ InitializeParallelDSM(ParallelContext *pcxt)
 	 */
 	segsize = shm_toc_estimate(&pcxt->estimator);
 	if (pcxt->nworkers != 0)
-		pcxt->seg = dsm_create(segsize, DSM_CREATE_NULL_IF_MAXSEGMENTS);
+		pcxt->seg = dsm_create("parallel worker", segsize,
+							   DSM_CREATE_NULL_IF_MAXSEGMENTS);
 	if (pcxt->seg != NULL)
 		pcxt->toc = shm_toc_create(PARALLEL_MAGIC,
 								   dsm_segment_address(pcxt->seg),
diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c
index 573c54d..7166328 100644
--- a/src/backend/storage/ipc/dsm.c
+++ b/src/backend/storage/ipc/dsm.c
@@ -80,8 +80,10 @@ struct dsm_segment
 /* Shared-memory state for a dynamic shared memory segment. */
 typedef struct dsm_control_item
 {
-	dsm_handle	handle;
+	dsm_handle	handle;			/* segment identifier */
 	uint32		refcnt;			/* 2+ = active, 1 = moribund, 0 = gone */
+	Size		size;			/* current size */
+	char		name[SHMEM_INDEX_KEYSIZE]; /* informational name */
 } dsm_control_item;
 
 /* Layout of the dynamic shared memory control segment. */
@@ -454,15 +456,18 @@ dsm_set_control_handle(dsm_handle h)
  * Create a new dynamic shared memory segment.
  */
 dsm_segment *
-dsm_create(Size size, int flags)
+dsm_create(const char *name, Size size, int flags)
 {
 	dsm_segment *seg;
-	uint32		i;
-	uint32		nitems;
+	dsm_control_item *item;
+	uint32		slot;
 
 	/* Unsafe in postmaster (and pointless in a stand-alone backend). */
 	Assert(IsUnderPostmaster);
 
+	Assert(name != NULL && strlen(name) > 0 &&
+		   strlen(name) < SHMEM_INDEX_KEYSIZE - 1);
+
 	if (!dsm_init_done)
 		dsm_backend_startup();
 
@@ -482,23 +487,18 @@ dsm_create(Size size, int flags)
 	/* Lock the control segment so we can register the new segment. */
 	LWLockAcquire(DynamicSharedMemoryControlLock, LW_EXCLUSIVE);
 
-	/* Search the control segment for an unused slot. */
-	nitems = dsm_control->nitems;
-	for (i = 0; i < nitems; ++i)
+	/*
+	 * Search the control segment for an unused slot that's previously been
+	 * used. If we don't find one initialize a new one if there's still space.
+	 */
+	for (slot = 0; slot < dsm_control->nitems; ++slot)
 	{
-		if (dsm_control->item[i].refcnt == 0)
-		{
-			dsm_control->item[i].handle = seg->handle;
-			/* refcnt of 1 triggers destruction, so start at 2 */
-			dsm_control->item[i].refcnt = 2;
-			seg->control_slot = i;
-			LWLockRelease(DynamicSharedMemoryControlLock);
-			return seg;
-		}
+		if (dsm_control->item[slot].refcnt == 0)
+			break;
 	}
 
-	/* Verify that we can support an additional mapping. */
-	if (nitems >= dsm_control->maxitems)
+	/* Verify that we can support the mapping. */
+	if (slot >= dsm_control->maxitems)
 	{
 		if ((flags & DSM_CREATE_NULL_IF_MAXSEGMENTS) != 0)
 		{
@@ -516,12 +516,23 @@ dsm_create(Size size, int flags)
 				 errmsg("too many dynamic shared memory segments")));
 	}
 
-	/* Enter the handle into a new array slot. */
-	dsm_control->item[nitems].handle = seg->handle;
+	item = &dsm_control->item[slot];
+	item->handle = seg->handle;
 	/* refcnt of 1 triggers destruction, so start at 2 */
-	dsm_control->item[nitems].refcnt = 2;
-	seg->control_slot = nitems;
-	dsm_control->nitems++;
+	item->refcnt = 2;
+	item->size = size;
+	strncpy(item->name, name, SHMEM_INDEX_KEYSIZE);
+	item->name[SHMEM_INDEX_KEYSIZE - 1] = 0;
+
+	seg->control_slot = slot;
+
+	/*
+	 * Increase number of initilized slots if we didn't reuse a previously
+	 * used one.
+	 */
+	if (slot >= dsm_control->nitems)
+		dsm_control->nitems++;
+
 	LWLockRelease(DynamicSharedMemoryControlLock);
 
 	return seg;
@@ -674,6 +685,10 @@ dsm_resize(dsm_segment *seg, Size size)
 	Assert(seg->control_slot != INVALID_CONTROL_SLOT);
 	dsm_impl_op(DSM_OP_RESIZE, seg->handle, size, &seg->impl_private,
 				&seg->mapped_address, &seg->mapped_size, ERROR);
+
+	/* persist the changed size */
+	dsm_control->item[seg->control_slot].size = size;
+
 	return seg->mapped_address;
 }
 
diff --git a/src/include/storage/dsm.h b/src/include/storage/dsm.h
index 86ede7a..278a1ac 100644
--- a/src/include/storage/dsm.h
+++ b/src/include/storage/dsm.h
@@ -31,7 +31,7 @@ extern void dsm_set_control_handle(dsm_handle h);
 #endif
 
 /* Functions that create, update, or remove mappings. */
-extern dsm_segment *dsm_create(Size size, int flags);
+extern dsm_segment *dsm_create(const char *name, Size size, int flags);
 extern dsm_segment *dsm_attach(dsm_handle h);
 extern void *dsm_resize(dsm_segment *seg, Size size);
 extern void *dsm_remap(dsm_segment *seg);
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 5bd2820..13ad00c 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -125,7 +125,7 @@ setup_dynamic_shared_memory(int64 queue_size, int nworkers,
 	segsize = shm_toc_estimate(&e);
 
 	/* Create the shared memory segment and establish a table of contents. */
-	seg = dsm_create(shm_toc_estimate(&e), 0);
+	seg = dsm_create("test_shm_mq", shm_toc_estimate(&e), 0);
 	toc = shm_toc_create(PG_TEST_SHM_MQ_MAGIC, dsm_segment_address(seg),
 						 segsize);
 
-- 
2.7.0.229.g701fa7f

