From 83e3657f39ee3ffb4be72a3510d85c62b9e1b3d6 Mon Sep 17 00:00:00 2001 From: Peter Shipton Date: Thu, 28 Nov 2024 15:59:18 -0500 Subject: [PATCH] Ensure ReferenceQueue/Reference synchronization order in enqueueImpl Signed-off-by: Peter Shipton --- .../classes/java/lang/ref/Reference.java | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/jcl/src/java.base/share/classes/java/lang/ref/Reference.java b/jcl/src/java.base/share/classes/java/lang/ref/Reference.java index 6da365e2c9e..f2f61aadbfe 100644 --- a/jcl/src/java.base/share/classes/java/lang/ref/Reference.java +++ b/jcl/src/java.base/share/classes/java/lang/ref/Reference.java @@ -194,24 +194,31 @@ public boolean isEnqueued () { @NotCheckpointSafe /*[ENDIF] CRIU_SUPPORT */ boolean enqueueImpl() { - final ReferenceQueue tempQueue; boolean result; T tempReferent = referent; - synchronized(this) { - /* Static order for the following code (DO NOT CHANGE) */ - tempQueue = queue; - queue = null; - if (state == STATE_ENQUEUED || tempQueue == null) { - return false; - } - result = tempQueue.enqueue(this); - if (result) { - state = STATE_ENQUEUED; - if (null != tempReferent) { - reprocess(); + ReferenceQueue tempQueue = queue; + while (true) { + synchronized(tempQueue) { + synchronized(this) { + if (tempQueue != queue) { + break; + } + /* Static order for the following code (DO NOT CHANGE) */ + queue = null; + if (state == STATE_ENQUEUED || tempQueue == null) { + return false; + } + result = tempQueue.enqueue(this); + if (result) { + state = STATE_ENQUEUED; + if (null != tempReferent) { + reprocess(); + } + } + return result; } } - return result; + tempQueue = queue; } }