diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
index acf6ff74f98..1c0f39e11ec 100644
--- a/doc/src/sgml/xfunc.sgml
+++ b/doc/src/sgml/xfunc.sgml
@@ -3628,7 +3628,7 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray
       Add-ins can reserve shared memory on server startup.  To do so, the
       add-in's shared library must be preloaded by specifying it in
       <xref linkend="guc-shared-preload-libraries"/><indexterm><primary>shared_preload_libraries</primary></indexterm>.
-      The shared library should register callbacks in its
+      The shared library should register callbacks in
       its <function>_PG_init</function> function, which then get called at the
       right stages of the system startup to initialize the shared memory.
       Here is an example:
@@ -3692,11 +3692,11 @@ my_shmem_init(void *arg)
 }
 
 </programlisting>
-      The <function>request_fn</function> callback is called during system
+      The <function>shmem_request_fn</function> callback is called during system
       startup, before the shared memory has been allocated. It should call
       <function>ShmemRequestStruct()</function> to register the add-in's
       shared memory needs. Note that <function>ShmemRequestStruct()</function>
-      doesn'' immediately allocate or initialize the memory, it merely
+      doesn't immediately allocate or initialize the memory, it merely
       registers the space to be allocated later in the startup sequence.  When
       the memory is allocated, it is initialized to zero.  To any more complex
       initialization, set the <function>init_fn()</function> callback, which
@@ -3726,7 +3726,7 @@ my_shmem_init(void *arg)
       libraries that are not specified in
       <xref linkend="guc-shared-preload-libraries"/><indexterm><primary>shared_preload_libraries</primary></indexterm>.
       However, after startup the allocation can fail if there is not enough
-      shared memory available. The system reserves a somes memory for
+      shared memory available. The system reserves some memory for
       allocations after startup, but that reservation is small.
      </para>
      <para>
@@ -3739,8 +3739,8 @@ my_shmem_init(void *arg)
       When <function>RegisterShmemCallbacks()</function> is called after
       startup, it will immediately call the appropriate callbacks, depending
       on whether the requested memory areas were already initialized by
-      another backend. The callbacks will be held while holding an internal
-      lock, which prevents concurrent two backends from initializating the
+      another backend. The callbacks will be called while holding an internal
+      lock, which prevents multiple backends from initializating the
       memory area concurrently.
      </para>
     </sect3>
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index de843d03c50..cef16327263 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -27,7 +27,7 @@
  *
  * Shared memory areas should usually not be allocated after postmaster
  * startup, although we do allow small allocations later for the benefit of
- * extension modules that loaded after startup.  Despite that allowance,
+ * extension modules that are loaded after startup.  Despite that allowance,
  * extensions that need shared memory should be added in
  * shared_preload_libraries, because the allowance is quite small and there is
  * no guarantee that any memory is available after startup.
@@ -50,7 +50,7 @@
  * -----
  *
  * To allocate shared memory, you need to register a set of callback functions
- * which handle the lifecycle of the allocation.  In the register_fn
+ * which handle the lifecycle of the allocation.  In the request_fn 
  * callback, fill in a ShmemStructDesc descriptor with the name, size, and any
  * other options, and call ShmemRequestStruct().  Leave any unused fields as
  * zeros.
@@ -90,12 +90,12 @@
  * ---------
  *
  * Initializing shared memory happens in multiple phases. In the first phase,
- * during postmaster startup, all the shmem_request callbacks are called.
- * Only after all all the request callbacks have been called and all the shmem
- * areas have been requested by the ShmemRequestStruct() calls we know how
- * much shared memory we need in total. After that, postmaster allocates
- * global shared memory segment, and calls all the init_fn callbacks to
- * initialize all the requested shmem areas.
+ * during postmaster startup, all the shmem_request callbacks are called.  Only
+ * after all the request callbacks have been called and all the shmem areas have
+ * been requested by the ShmemRequestStruct() calls we know how much shared
+ * memory we need in total. After that, postmaster allocates global shared
+ * memory segment, allocates memory to the requested areas, and calls all the
+ * init_fn callbacks to initialize all the requested shmem areas.
  *
  * In standard Unix-ish environments, individual backends do not need to
  * re-establish their local pointers into shared memory, because they inherit
@@ -290,16 +290,12 @@ Datum		pg_numa_available(PG_FUNCTION_ARGS);
 void
 ShmemRequestStruct(ShmemStructDesc *desc)
 {
-	ListCell *lc;
-
 	if (shmem_startup_state != SB_REQUESTING)
 		elog(ERROR, "ShmemRequestStruct can only be called from a shmem_request callback");
 
 	/* Check that it's not already registered in this process */
-	foreach(lc, requested_shmem_areas)
+	foreach_ptr(ShmemStructDesc, existing, requested_shmem_areas)
 	{
-		ShmemStructDesc *existing = (ShmemStructDesc *) lfirst(lc);
-
 		if (strcmp(existing->name, desc->name) == 0)
 			ereport(ERROR,
 					(errmsg("shared memory struct \"%s\" is already registered",
@@ -319,7 +315,6 @@ ShmemRequestStruct(ShmemStructDesc *desc)
 size_t
 ShmemGetRequestedSize(void)
 {
-	ListCell   *lc;
 	size_t		size;
 
 	/* memory needed for the ShmemIndex */
@@ -327,10 +322,8 @@ ShmemGetRequestedSize(void)
 							  sizeof(ShmemIndexEnt));
 
 	/* memory needed for all the requested areas */
-	foreach(lc, requested_shmem_areas)
+	foreach_ptr(ShmemStructDesc, desc, requested_shmem_areas)
 	{
-		ShmemStructDesc *desc = (ShmemStructDesc *) lfirst(lc);
-
 		size = add_size(size, desc->size);
 		size = add_size(size, desc->extra_size);
 	}
@@ -358,12 +351,9 @@ ShmemInitRequested(void)
 	 * Initialize all the requested memory areas.  There are no concurrent
 	 * processes yet, so no need for locking.
 	 */
-	foreach(lc, requested_shmem_areas)
-	{
-		ShmemStructDesc *desc = (ShmemStructDesc *) lfirst(lc);
-
+	foreach_ptr(ShmemStructDesc, desc, requested_shmem_areas)
 		AttachOrInit(desc, true, false);
-	}
+
 	list_free(requested_shmem_areas);
 	requested_shmem_areas = NIL;
 
@@ -465,24 +455,26 @@ AttachOrInit(ShmemStructDesc *desc, bool init_allowed, bool attach_allowed)
 				break;
 		}
 	}
-	else if (!init_allowed)
-	{
-		/* attach was requested, but it was not found */
-		ereport(FATAL,
-				(errcode(ERRCODE_OUT_OF_MEMORY),
-				 errmsg("could not find ShmemIndex entry for data structure \"%s\"",
-						desc->name)));
-	}
-	else if (!index_entry)
-	{
-		/* tried to add it to the hash table, but there was no space */
-		ereport(ERROR,
-				(errcode(ERRCODE_OUT_OF_MEMORY),
-				 errmsg("could not create ShmemIndex entry for data structure \"%s\"",
-						desc->name)));
-	}
 	else
 	{
+		if (!init_allowed)
+		{
+			/* The entry is not found and the caller expected it to be present. */
+			ereport(FATAL,
+					(errcode(ERRCODE_OUT_OF_MEMORY),
+					 errmsg("could not find ShmemIndex entry for data structure \"%s\"",
+							desc->name)));
+		}
+
+		if (!index_entry)
+		{
+			/* tried to add it to the hash table, but there was no space */
+			ereport(ERROR,
+					(errcode(ERRCODE_OUT_OF_MEMORY),
+					 errmsg("could not create ShmemIndex entry for data structure \"%s\"",
+							desc->name)));
+		}
+
 		/*
 		 * We inserted the entry to the shared memory index. Allocate
 		 * requested amount of shared memory for it, and do basic
@@ -729,7 +721,7 @@ ShmemAddrIsValid(const void *addr)
  * backend startup, to allocate and initialize the area.
  *
  * This is normally called early during postmaster startup, but if the
- * SHMEM_ALLOW_AFTER_STARTUP is set, this can also be used after startup,
+ * SHMEM_CB_ALLOW_AFTER_STARTUP is set, this can also be used after startup,
  * although after startup there's no guarantee that there's enough shared
  * memory available.  When called after startup, this immediately calls the
  * right callbacks depending on whether another backend had already
@@ -744,7 +736,7 @@ RegisterShmemCallbacks(const ShmemCallbacks *callbacks)
 		ListCell   *lc;
 		bool		found = false;
 
-		if ((callbacks->flags & SHMEM_ALLOW_AFTER_STARTUP) == 0)
+		if ((callbacks->flags & SHMEM_CB_ALLOW_AFTER_STARTUP) == 0)
 			elog(ERROR, "FIXME: not allowed after startup");
 
 		Assert(requested_shmem_areas == NIL);
@@ -756,12 +748,8 @@ RegisterShmemCallbacks(const ShmemCallbacks *callbacks)
 
 		LWLockAcquire(ShmemIndexLock, LW_EXCLUSIVE);
 
-		foreach(lc, requested_shmem_areas)
-		{
-			ShmemStructDesc *desc = (ShmemStructDesc *) lfirst(lc);
-
+		foreach_ptr(ShmemStructDesc, desc, requested_shmem_areas)
 			found = AttachOrInit(desc, true, true);
-		}
 
 		/*
 		 * FIXME: What to do if multiple shmem areas were requested, and some
diff --git a/src/include/storage/shmem.h b/src/include/storage/shmem.h
index 720941e219e..a79d0a52528 100644
--- a/src/include/storage/shmem.h
+++ b/src/include/storage/shmem.h
@@ -62,10 +62,10 @@ typedef struct ShmemStructDesc
 	size_t		extra_size;
 
 	/*
-	 * When the shmem area is initialized or attached to, pointer to it is
-	 * stored in *ptr.  It usually points to a global variable, used to access
-	 * the shared memory area later.  *ptr is set before the init_fn or
-	 * attach_fn callback is called.
+	 * When the shmem area is initialized or attached to, pointer to it is stored
+	 * in *ptr which is expected to point to a global variable, used to access
+	 * the shared memory area later.  *ptr is set before the init_fn or attach_fn
+	 * callback is called.
 	 */
 	void	  **ptr;
 } ShmemStructDesc;
@@ -127,6 +127,20 @@ typedef void (*ShmemRequestCallback) (void *arg);
 typedef void (*ShmemInitCallback) (void *arg);
 typedef void (*ShmemAttachCallback) (void *arg);
 
+
+/*
+ * Flags to control the behavior of RegisterShmemCallbacks().
+ *
+ * SHMEM_CB_ALLOW_AFTER_STARTUP: Allow these shared memory usages to be registered
+ * after postmaster startup. Normally, registering a shared memory system after
+ * postmaster startup is not allowed e.g. in an add-in library loaded on-demaind
+ * in a backend.  If a subsystem sets this flag, the callbacks are called
+ * immediately after registration, to initialize or attach to the requested
+ * shared memory areas. This is not used by any built-in subsystems, but
+ * extensions can find it useful.
+ */
+#define SHMEM_CB_ALLOW_AFTER_STARTUP		0x00000001
+
 /*
  * Shared memory is reserved and allocated in stages at postmaster startup,
  * and in EXEC_BACKEND mode, there's some extra work done to "attach" to them
@@ -135,7 +149,7 @@ typedef void (*ShmemAttachCallback) (void *arg);
  */
 typedef struct ShmemCallbacks
 {
-	/* SHMEM_* flags */
+	/* SHMEM_CB_* flags */
 	int			flags;
 
 	/*
@@ -164,18 +178,6 @@ typedef struct ShmemCallbacks
 	void	   *attach_fn_arg;
 } ShmemCallbacks;
 
-/*
- * Allow these shared memory allocations after postmaster startup.  Normally,
- * RegisterShmemCallbacks() errors out if it's called after postmaster startup
- * e.g. in an add-in library loaded on-demaind in a backend.  If you set this
- * flag, RegisterShmemCallbacks() will instead immediately call the callbacks,
- * to initialize or attach to the requested shared memory areas.
- *
- * This is not used by any built-in subsystems, but extensions can find it
- * useful.
- */
-#define SHMEM_ALLOW_AFTER_STARTUP		0x00000001
-
 /* shmem.c */
 extern PGDLLIMPORT slock_t *ShmemLock;
 typedef struct PGShmemHeader PGShmemHeader; /* avoid including
