1 /******************************************************************************* 2 * Copyright (c) 2004, 2013 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 * Danail Nachev (Prosyst) - bug 185654 14 * Andrei Loskutov - bug 44735 15 *******************************************************************************/ 16 package org.eclipse.osgi.internal.location; 17 18 import java.io.*; 19 import java.nio.channels.FileLock; 20 import java.nio.channels.OverlappingFileLockException; 21 import org.eclipse.osgi.internal.messages.Msg; 22 import org.eclipse.osgi.util.NLS; 23 24 /** 25 * Internal class. 26 */ 27 public class Locker_JavaNio implements Locker { 28 private final File lockFile; 29 private final boolean debug; 30 private FileLock fileLock; 31 private RandomAccessFile raFile; 32 Locker_JavaNio(File lockFile, boolean debug)33 public Locker_JavaNio(File lockFile, boolean debug) { 34 this.lockFile = lockFile; 35 this.debug = debug; 36 } 37 38 @Override lock()39 public synchronized boolean lock() throws IOException { 40 raFile = new RandomAccessFile(lockFile, "rw"); //$NON-NLS-1$ 41 try { 42 /* 43 * fix for bug http://bugs.sun.com/view_bug.do?bug_id=6628575 and 44 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=44735#c17 45 */ 46 fileLock = raFile.getChannel().tryLock(0, 1, false); 47 } catch (IOException ioe) { 48 // print exception if debugging 49 if (debug) 50 System.out.println(NLS.bind(Msg.location_cannotLock, lockFile)); 51 // produce a more specific message for clients 52 String specificMessage = NLS.bind(Msg.location_cannotLockNIO, new Object[] {lockFile, ioe.getMessage(), "\"-D" + LocationHelper.PROP_OSGI_LOCKING + "=none\""}); //$NON-NLS-1$ //$NON-NLS-2$ 53 throw new IOException(specificMessage); 54 } catch (OverlappingFileLockException e) { 55 // handle it as null result 56 fileLock = null; 57 } finally { 58 if (fileLock != null) 59 return true; 60 raFile.close(); 61 raFile = null; 62 } 63 return false; 64 } 65 66 @Override release()67 public synchronized void release() { 68 if (fileLock != null) { 69 try { 70 fileLock.release(); 71 } catch (IOException e) { 72 //don't complain, we're making a best effort to clean up 73 } 74 fileLock = null; 75 } 76 if (raFile != null) { 77 try { 78 raFile.close(); 79 } catch (IOException e) { 80 //don't complain, we're making a best effort to clean up 81 } 82 raFile = null; 83 } 84 } 85 86 @Override isLocked()87 public synchronized boolean isLocked() throws IOException { 88 if (fileLock != null) 89 return true; 90 try { 91 RandomAccessFile temp = new RandomAccessFile(lockFile, "rw"); //$NON-NLS-1$ 92 FileLock tempLock = null; 93 try { 94 /* 95 * fix for bug http://bugs.sun.com/view_bug.do?bug_id=6628575 and 96 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=44735#c17 97 */ 98 try { 99 tempLock = temp.getChannel().tryLock(0, 1, false); 100 } catch (IOException ioe) { 101 if (debug) 102 System.out.println(NLS.bind(Msg.location_cannotLock, lockFile)); 103 // produce a more specific message for clients 104 String specificMessage = NLS.bind(Msg.location_cannotLockNIO, new Object[] {lockFile, ioe.getMessage(), "\"-D" + LocationHelper.PROP_OSGI_LOCKING + "=none\""}); //$NON-NLS-1$ //$NON-NLS-2$ 105 throw new IOException(specificMessage); 106 } 107 if (tempLock != null) { 108 tempLock.release(); // allow IOException to propagate because that would mean it is still locked 109 return false; 110 } 111 return true; 112 } catch (OverlappingFileLockException e) { 113 return true; 114 } finally { 115 temp.close(); 116 } 117 } catch (FileNotFoundException e) { 118 return false; 119 } 120 } 121 } 122