From ca6e1aecc352d16fd2a731ad6e388b018b9ae4b0 Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Tue, 24 Feb 2009 14:01:45 -0800 Subject: [PATCH] 6803402: Race condition in AbstractQueuedSynchronizer Read fields in reverse initialization order Reviewed-by: martin --- .../concurrent/locks/AbstractQueuedLongSynchronizer.java | 6 ++++-- .../util/concurrent/locks/AbstractQueuedSynchronizer.java | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java index 2b0f36c523d..a7f048e8bdb 100644 --- a/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java +++ b/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java @@ -1222,8 +1222,10 @@ public abstract class AbstractQueuedLongSynchronizer // The correctness of this depends on head being initialized // before tail and on head.next being accurate if the current // thread is first in queue. - Node h, s; - return (h = head) != tail && + Node t = tail; // Read fields in reverse initialization order + Node h = head; + Node s; + return h != t && ((s = h.next) == null || s.thread != Thread.currentThread()); } diff --git a/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java index 597e15270ae..39219bb5fd9 100644 --- a/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java +++ b/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java @@ -1445,8 +1445,10 @@ public abstract class AbstractQueuedSynchronizer // The correctness of this depends on head being initialized // before tail and on head.next being accurate if the current // thread is first in queue. - Node h, s; - return (h = head) != tail && + Node t = tail; // Read fields in reverse initialization order + Node h = head; + Node s; + return h != t && ((s = h.next) == null || s.thread != Thread.currentThread()); }