Hi, One more patch regarding deadlock detection. https://bugs.openjdk.java.net/show_bug.cgi?id=100059
Deadlock detection mechanism assumes that thread cannot block itself. In general this is not right, especially in case of non-reentrant mutexes. One of such examples we can find here (FIFOMutex sample): http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/LockSupport.html To fix this, we just need to drop unnecessary code. Attached updated patch and testcase Thanks, Dmytro
hotspot0.diff
Description: Binary data
/* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * @test * @bug TBD * @summary Enter non-reentrant lock twice, expecting deadlock with a single thread cycle. * * @run main/othervm SelfDeadlockTest */ import java.lang.management.*; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; import java.util.concurrent.locks.*; public class SelfDeadlockTest implements Runnable { static FIFOMutex mutex = new FIFOMutex(); public static void main(String... args) throws Exception { Thread thread = new Thread(new SelfDeadlockTest()); thread.setDaemon(true); thread.start(); Thread.sleep(1000); long[] expected = new long[] { thread.getId() }; long[] actual = ManagementFactory.getThreadMXBean().findDeadlockedThreads(); if (!Arrays.equals(expected, actual)) { throw new AssertionError("expected: " + Arrays.toString(expected) + "; actual: " + Arrays.toString(actual)); } System.out.println("Test passed"); } public void run() { mutex.lock(); mutex.lock(); } } class FIFOMutex extends AbstractOwnableSynchronizer { private final AtomicBoolean locked = new AtomicBoolean(false); private final Queue<Thread> waiters = new ConcurrentLinkedQueue<Thread>(); public void lock() { boolean wasInterrupted = false; Thread current = Thread.currentThread(); waiters.add(current); // Block while not first in queue or cannot acquire lock while (waiters.peek() != current || !locked.compareAndSet(false, true)) { LockSupport.park(this); if (Thread.interrupted()) // ignore interrupts while waiting wasInterrupted = true; } setExclusiveOwnerThread(current); waiters.remove(); if (wasInterrupted) // reassert interrupt status on exit current.interrupt(); } public void unlock() { setExclusiveOwnerThread(null); locked.set(false); LockSupport.unpark(waiters.peek()); } }