Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmit Kapila2020-09-01 02:41:39 +0000
committerAmit Kapila2020-09-01 02:41:39 +0000
commit4ab77697f67aa5b90b032b9175b46901859da6d7 (patch)
tree94bec8c0703eae0b770489d6156a22d752c3cd18
parentab3c6d41552411ea2fe4904ec8294951c52c113d (diff)
Fix the SharedFileSetUnregister API.
Commit 808e13b282 introduced a few APIs to extend the existing Buffile interface. In SharedFileSetDeleteOnProcExit, it tries to delete the list element while traversing the list with 'foreach' construct which makes the behavior of list traversal unpredictable. Author: Amit Kapila Reviewed-by: Dilip Kumar Tested-by: Dilip Kumar and Neha Sharma Discussion: https://postgr.es/m/CAA4eK1JhLatVcQ2OvwA_3s0ih6Hx9+kZbq107cXVsSWWukH7vA@mail.gmail.com
-rw-r--r--src/backend/storage/file/sharedfileset.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/src/backend/storage/file/sharedfileset.c b/src/backend/storage/file/sharedfileset.c
index 8b96e81ffff..859c22e79b6 100644
--- a/src/backend/storage/file/sharedfileset.c
+++ b/src/backend/storage/file/sharedfileset.c
@@ -266,12 +266,16 @@ SharedFileSetOnDetach(dsm_segment *segment, Datum datum)
static void
SharedFileSetDeleteOnProcExit(int status, Datum arg)
{
- ListCell *l;
-
- /* Loop over all the pending shared fileset entry */
- foreach(l, filesetlist)
+ /*
+ * Remove all the pending shared fileset entries. We don't use foreach() here
+ * because SharedFileSetDeleteAll will remove the current element in
+ * filesetlist. Though we have used foreach_delete_current() to remove the
+ * element from filesetlist it could only fix up the state of one of the
+ * loops, see SharedFileSetUnregister.
+ */
+ while (list_length(filesetlist) > 0)
{
- SharedFileSet *fileset = (SharedFileSet *) lfirst(l);
+ SharedFileSet *fileset = (SharedFileSet *) linitial(filesetlist);
SharedFileSetDeleteAll(fileset);
}
@@ -301,7 +305,7 @@ SharedFileSetUnregister(SharedFileSet *input_fileset)
/* Remove the entry from the list */
if (input_fileset == fileset)
{
- filesetlist = list_delete_cell(filesetlist, l);
+ filesetlist = foreach_delete_current(filesetlist, l);
return;
}
}