/*
 * Copyright 2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/*
 * @test
 * @bug 6571733 6460501
 * @summary Check that regaining a read lock succeeds after a write
 *          lock attempt times out
 */
import java.util.concurrent.locks.*;
import java.util.concurrent.*;

public class Bug6571733 {

    void test(String[] args) throws Throwable {
        test(true);
        test(false);
    }

    void test(boolean fairness) throws Throwable {
        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fairness);

        // obtain read lock
        lock.readLock().lock();

        Thread thread = new Thread() { public void run() {
            try {
                check (! lock.writeLock().tryLock(0, TimeUnit.DAYS));

                lock.readLock().lock();
                lock.readLock().unlock();
            } catch (Throwable t) { unexpected(t); }}};

        thread.start();
        thread.join();
    }

    //--------------------- Infrastructure ---------------------------
    volatile int passed = 0, failed = 0;
    void pass() {passed++;}
    void fail() {failed++; Thread.dumpStack();}
    void fail(String msg) {System.err.println(msg); fail();}
    void unexpected(Throwable t) {failed++; t.printStackTrace();}
    void check(boolean cond) {if (cond) pass(); else fail();}
    public static void main(String[] args) throws Throwable {
        new Bug6571733().instanceMain(args);}
    void instanceMain(String[] args) throws Throwable {
        try {test(args);} catch (Throwable t) {unexpected(t);}
        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
        if (failed > 0) throw new AssertionError("Some tests failed");}
}
