Allow DSM segments to be created as pinned
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 24 Mar 2017 22:27:22 +0000 (19:27 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 28 Mar 2017 22:44:30 +0000 (19:44 -0300)
dsm_create and dsm_attach assumed that a current resource owner was
always in place.  Exploration with the API show that this is
inconvenient: sometimes one must create a dummy resowner, create/attach
the DSM, only to pin the mapping later, which is wasteful.  Change
create/attach so that if there is no current resowner, the dsm is
effectively pinned right from the start.

Discussion: https://postgr.es/m/20170324232710.32acsfsvjqfgc6ud@alvherre.pgsql
Reviewed by Thomas Munro.

src/backend/storage/ipc/dsm.c

index 54378bcea98bfd0fd047037a4c5591d3b09c25f3..b65b63b721f0fd4fcb186ec4a17fc90c100a26fa 100644 (file)
@@ -453,6 +453,13 @@ dsm_set_control_handle(dsm_handle h)
 
 /*
  * Create a new dynamic shared memory segment.
+ *
+ * If there is a non-NULL CurrentResourceOwner, the new segment is associated
+ * with it and must be detached before the resource owner releases, or a
+ * warning will be logged.  If CurrentResourceOwner is NULL, the segment
+ * remains attached until explicitely detached or the session ends.
+ * Creating with a NULL CurrentResourceOwner is equivalent to creating
+ * with a non-NULL CurrentResourceOwner and then calling dsm_pin_mapping.
  */
 dsm_segment *
 dsm_create(Size size, int flags)
@@ -544,6 +551,11 @@ dsm_create(Size size, int flags)
  * This can happen if we're asked to attach the segment, but then everyone
  * else detaches it (causing it to be destroyed) before we get around to
  * attaching it.
+ *
+ * If there is a non-NULL CurrentResourceOwner, the attached segment is
+ * associated with it and must be detached before the resource owner releases,
+ * or a warning will be logged.  Otherwise the segment remains attached until
+ * explicitely detached or the session ends.  See the note atop dsm_create().
  */
 dsm_segment *
 dsm_attach(dsm_handle h)
@@ -1095,7 +1107,8 @@ dsm_create_descriptor(void)
 {
        dsm_segment *seg;
 
-       ResourceOwnerEnlargeDSMs(CurrentResourceOwner);
+       if (CurrentResourceOwner)
+               ResourceOwnerEnlargeDSMs(CurrentResourceOwner);
 
        seg = MemoryContextAlloc(TopMemoryContext, sizeof(dsm_segment));
        dlist_push_head(&dsm_segment_list, &seg->node);
@@ -1107,7 +1120,8 @@ dsm_create_descriptor(void)
        seg->mapped_size = 0;
 
        seg->resowner = CurrentResourceOwner;
-       ResourceOwnerRememberDSM(CurrentResourceOwner, seg);
+       if (CurrentResourceOwner)
+               ResourceOwnerRememberDSM(CurrentResourceOwner, seg);
 
        slist_init(&seg->on_detach);