1 /* 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.io.File; 25 import java.io.IOException; 26 import java.io.RandomAccessFile; 27 import java.lang.ref.Reference; 28 import java.lang.ref.WeakReference; 29 import java.nio.channels.FileLock; 30 import java.nio.channels.OverlappingFileLockException; 31 import java.nio.file.Files; 32 import java.nio.file.Path; 33 import jdk.test.lib.util.FileUtils; 34 35 /* 36 * @test 37 * @bug 8166253 38 * @summary Verify that OverlappingFileLockException is thrown when expected. 39 * @library .. /test/lib 40 * @build jdk.test.lib.util.FileUtils 41 * @run main/othervm FileLockGC 42 */ 43 public class FileLockGC { 44 public enum TestType { 45 NO_GC_NO_RELEASE(true), 46 // A hypothetical 'GC_THEN_RELEASE' case is infeasible 47 RELEASE(false), 48 RELEASE_THEN_GC(false), 49 GC(true); 50 51 private final boolean exceptionExpected; 52 53 TestType(boolean exceptionExpected) { 54 this.exceptionExpected = exceptionExpected; 55 } 56 57 boolean exceptionExpected() { 58 return exceptionExpected; 59 } 60 } 61 62 public static void main(String[] args) throws Exception { 63 final File f = new File(System.getProperty("test.dir", ".") 64 + File.separator + "junk.txt"); 65 final Path p = f.toPath(); 66 int failures = 0; 67 68 for (TestType t : TestType.values()) { 69 try { 70 if (!testFileLockGC(f, t)) { 71 failures++; 72 } 73 } finally { 74 FileUtils.deleteFileIfExistsWithRetry(p); 75 } 76 } 77 78 if (failures != 0) { 79 throw new RuntimeException("Test had " + failures + " failure(s)"); 80 } 81 } 82 83 private static boolean testFileLockGC(File f, TestType type) 84 throws InterruptedException, IOException { 85 System.out.printf("Test %s starting%n", type.toString()); 86 87 final RandomAccessFile raf1 = new RandomAccessFile(f, "rw"); 88 89 FileLock lock1 = raf1.getChannel().tryLock(); 90 WeakReference<FileLock> ref1 = new WeakReference(lock1); 91 92 switch (type) { 93 case GC: 94 lock1 = null; 95 do { 96 System.gc(); 97 Thread.sleep(10); 98 } while (ref1.get() != null); 99 break; 100 case RELEASE: 101 lock1.release(); 102 break; 103 case RELEASE_THEN_GC: 104 lock1.release(); 105 lock1 = null; 106 do { 107 System.gc(); 108 Thread.sleep(10); 109 } while (ref1.get() != null); 110 break; 111 default: // NO_GC_NO_RELEASE 112 // lock1 is neither collected nor released 113 break; 114 } 115 116 final RandomAccessFile raf2 = new RandomAccessFile(f, "rw"); 117 118 boolean success = true; 119 FileLock lock2 = null; 120 try { 121 lock2 = raf2.getChannel().tryLock(); 122 if (type.exceptionExpected()) { 123 System.err.printf 124 ("No expected OverlappingFileLockException for test %s%n", 125 type.toString()); 126 success = false; 127 } 128 } catch (OverlappingFileLockException ofe) { 129 if (!type.exceptionExpected()) { 130 System.err.printf 131 ("Unexpected OverlappingFileLockException for test %s%n", 132 type.toString()); 133 success = false; 134 } 135 } finally { 136 if (lock1 != null) { 137 lock1.release(); 138 } 139 if (lock2 != null) { 140 lock2.release(); 141 } 142 raf2.close(); 143 raf1.close(); 144 System.out.printf("Test %s finished%n", type.toString()); 145 } 146 147 return success; 148 } 149 }