From dc6b3cd20a40da2da8e1e8dc0eaa64e3008f5516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 5 Mar 2024 13:30:02 +0100 Subject: [PATCH] Fix #19524: Protect use of `HeaderIdGenerator` with `synchronized`. Hopefully this is the only source of the race condition that we have been observing. --- .../comments/markdown/SectionRenderingExtension.scala | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SectionRenderingExtension.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SectionRenderingExtension.scala index 0acb1c02a69e..134ab17715fe 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SectionRenderingExtension.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/SectionRenderingExtension.scala @@ -35,7 +35,14 @@ object SectionRenderingExtension extends HtmlRenderer.HtmlRendererExtension: val idSuffix = repeatedIds.getOrElseUpdate((c, headerText), 0) val ifSuffixStr = if(idSuffix == 0) then "" else idSuffix.toString repeatedIds.update((c, headerText), idSuffix + 1) - val id = idGenerator.getId(headerText + ifSuffixStr) + + /* #19524 flexmark's `HeaderIdGenerator` does not appear to be thread-safe, + * so we protect its usage with a full `synchronize`. + */ + val id = idGenerator.synchronized { + idGenerator.getId(headerText + ifSuffixStr) + } + val anchor = AnchorLink(s"#$id") val headerClass: String = header.getLevel match case 1 => "h500"