Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6803402

Race condition in AbstractQueuedSynchronizer

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P2 P2
    • 7
    • 7
    • core-libs

        Martin Buchholz reports:

        While writing a test for this, I unearthed yet another race condition in AQS.
        Fortunately, it's in new jdk7 code.

        In the expression
        (h = head) != tail &&
        head may be read as null,
        then head and tail are both initialized before tail on RHS is read,
        yielding NPE

        Caused by: java.lang.NullPointerException
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.hasQueuedPredecessors(AbstractQueuedSynchronizer.java:1510)
        at java.util.concurrent.Semaphore$FairSync.tryAcquireShared(Semaphore.java:245)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1263)
        at java.util.concurrent.Semaphore.acquire(Semaphore.java:312)

        We need to read fields in the reverse order.

        @@ -1445,8 +1502,10 @@
                 // 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());
             }

              dholmes David Holmes
              dholmes David Holmes
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: