From cb9a0c7987466b130fbced01ab5d5481cf3a16df Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Mon, 10 Mar 2014 10:17:19 -0400 Subject: [PATCH] Teach on_exit_reset() to discard pending cleanups for dsm. 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 | 31 +++++++++++++++++++++++++++++++ src/backend/storage/ipc/ipc.c | 1 + src/include/storage/dsm.h | 1 + 3 files changed, 33 insertions(+) diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c index 327d685097..31e592e06e 100644 --- a/src/backend/storage/ipc/dsm.c +++ b/src/backend/storage/ipc/dsm.c @@ -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. */ diff --git a/src/backend/storage/ipc/ipc.c b/src/backend/storage/ipc/ipc.c index 9dc48c30b6..5dea0ed8dd 100644 --- a/src/backend/storage/ipc/ipc.c +++ b/src/backend/storage/ipc/ipc.c @@ -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(); } diff --git a/src/include/storage/dsm.h b/src/include/storage/dsm.h index 71901bf8c5..46d3cbdd8a 100644 --- a/src/include/storage/dsm.h +++ b/src/include/storage/dsm.h @@ -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 */ -- GitLab