Teach on_exit_reset() to discard pending cleanups for dsm.
authorRobert Haas
Mon, 10 Mar 2014 14:17:19 +0000 (10:17 -0400)
committerRobert Haas
Mon, 10 Mar 2014 14:17:19 +0000 (10:17 -0400)
If a postmaster child invokes fork() and then calls on_exit_reset, that
should be sufficient to let it exit() without breaking anything, but
dynamic shared memory broke that by not updating on_exit_reset() to
discard callbacks registered with dynamic shared memory segments.

Per investigation of a complaint from Tom Lane.

src/backend/storage/ipc/dsm.c
src/backend/storage/ipc/ipc.c
src/include/storage/dsm.h

index 327d6850971af4a19e3ea2c25c38a99a6149dcd7..31e592e06e7b74d1f5da052424110c9eb0fe3770 100644 (file)
@@ -979,6 +979,37 @@ cancel_on_dsm_detach(dsm_segment *seg, on_dsm_detach_callback function,
    }
 }
 
+/*
+ * Discard all registered on-detach callbacks without executing them.
+ */
+void
+reset_on_dsm_detach(void)
+{
+   dlist_iter      iter;
+
+   dlist_foreach(iter, &dsm_segment_list)
+   {
+       dsm_segment *seg = dlist_container(dsm_segment, node, iter.cur);
+
+       /* Throw away explicit on-detach actions one by one. */
+       while (!slist_is_empty(&seg->on_detach))
+       {
+           slist_node *node;
+           dsm_segment_detach_callback *cb;
+
+           node = slist_pop_head_node(&seg->on_detach);
+           cb = slist_container(dsm_segment_detach_callback, node, node);
+           pfree(cb);
+       }
+
+       /*
+        * Decrementing the reference count is a sort of implicit on-detach
+        * action; make sure we don't do that, either.
+        */
+       seg->control_slot = INVALID_CONTROL_SLOT;
+   }
+}
+
 /*
  * Create a segment descriptor.
  */
index 9dc48c30b611c5bf7550322a86d80ad2bc31e70f..5dea0ed8ddb3d646c2eadddf65346b988755f36f 100644 (file)
@@ -400,4 +400,5 @@ on_exit_reset(void)
    before_shmem_exit_index = 0;
    on_shmem_exit_index = 0;
    on_proc_exit_index = 0;
+   reset_on_dsm_detach();
 }
index 71901bf8c5acff7a87762770fc51953385a2eb98..46d3cbdd8ab6cd6ba576ef86b611025b8eec404d 100644 (file)
@@ -43,5 +43,6 @@ extern void on_dsm_detach(dsm_segment *seg,
              on_dsm_detach_callback function, Datum arg);
 extern void cancel_on_dsm_detach(dsm_segment *seg,
              on_dsm_detach_callback function, Datum arg);
+extern void reset_on_dsm_detach(void);
 
 #endif   /* DSM_H */