From 8d0802b308d65c83bf285f38992f97f748dd9456 Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Fri, 28 Aug 2020 12:42:09 +0530 Subject: [PATCH v55 1/5] 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. --- src/backend/storage/file/sharedfileset.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/backend/storage/file/sharedfileset.c b/src/backend/storage/file/sharedfileset.c index 8b96e81..859c22e 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; } } -- 1.8.3.1