133 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.util;
 | |
| 
 | |
| import com.google.common.base.Charsets;
 | |
| import java.io.IOException;
 | |
| import java.nio.ByteBuffer;
 | |
| import java.nio.channels.FileChannel;
 | |
| import java.nio.channels.FileLock;
 | |
| import java.nio.file.AccessDeniedException;
 | |
| import java.nio.file.NoSuchFileException;
 | |
| import java.nio.file.Path;
 | |
| import java.nio.file.StandardOpenOption;
 | |
| import net.minecraft.FileUtil;
 | |
| 
 | |
| public class DirectoryLock implements AutoCloseable {
 | |
| 	public static final String LOCK_FILE = "session.lock";
 | |
| 	private final FileChannel lockFile;
 | |
| 	private final FileLock lock;
 | |
| 	private static final ByteBuffer DUMMY;
 | |
| 
 | |
| 	public static DirectoryLock create(Path path) throws IOException {
 | |
| 		Path path2 = path.resolve("session.lock");
 | |
| 		FileUtil.createDirectoriesSafe(path);
 | |
| 		FileChannel fileChannel = FileChannel.open(path2, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
 | |
| 
 | |
| 		try {
 | |
| 			fileChannel.write(DUMMY.duplicate());
 | |
| 			fileChannel.force(true);
 | |
| 			FileLock fileLock = fileChannel.tryLock();
 | |
| 			if (fileLock == null) {
 | |
| 				throw DirectoryLock.LockException.alreadyLocked(path2);
 | |
| 			} else {
 | |
| 				return new DirectoryLock(fileChannel, fileLock);
 | |
| 			}
 | |
| 		} catch (IOException var6) {
 | |
| 			try {
 | |
| 				fileChannel.close();
 | |
| 			} catch (IOException var5) {
 | |
| 				var6.addSuppressed(var5);
 | |
| 			}
 | |
| 
 | |
| 			throw var6;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private DirectoryLock(FileChannel lockFile, FileLock lock) {
 | |
| 		this.lockFile = lockFile;
 | |
| 		this.lock = lock;
 | |
| 	}
 | |
| 
 | |
| 	public void close() throws IOException {
 | |
| 		try {
 | |
| 			if (this.lock.isValid()) {
 | |
| 				this.lock.release();
 | |
| 			}
 | |
| 		} finally {
 | |
| 			if (this.lockFile.isOpen()) {
 | |
| 				this.lockFile.close();
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public boolean isValid() {
 | |
| 		return this.lock.isValid();
 | |
| 	}
 | |
| 
 | |
| 	public static boolean isLocked(Path path) throws IOException {
 | |
| 		Path path2 = path.resolve("session.lock");
 | |
| 
 | |
| 		try {
 | |
| 			FileChannel fileChannel = FileChannel.open(path2, StandardOpenOption.WRITE);
 | |
| 
 | |
| 			boolean var4;
 | |
| 			try {
 | |
| 				FileLock fileLock = fileChannel.tryLock();
 | |
| 
 | |
| 				try {
 | |
| 					var4 = fileLock == null;
 | |
| 				} catch (Throwable var8) {
 | |
| 					if (fileLock != null) {
 | |
| 						try {
 | |
| 							fileLock.close();
 | |
| 						} catch (Throwable var7) {
 | |
| 							var8.addSuppressed(var7);
 | |
| 						}
 | |
| 					}
 | |
| 
 | |
| 					throw var8;
 | |
| 				}
 | |
| 
 | |
| 				if (fileLock != null) {
 | |
| 					fileLock.close();
 | |
| 				}
 | |
| 			} catch (Throwable var9) {
 | |
| 				if (fileChannel != null) {
 | |
| 					try {
 | |
| 						fileChannel.close();
 | |
| 					} catch (Throwable var6) {
 | |
| 						var9.addSuppressed(var6);
 | |
| 					}
 | |
| 				}
 | |
| 
 | |
| 				throw var9;
 | |
| 			}
 | |
| 
 | |
| 			if (fileChannel != null) {
 | |
| 				fileChannel.close();
 | |
| 			}
 | |
| 
 | |
| 			return var4;
 | |
| 		} catch (AccessDeniedException var10) {
 | |
| 			return true;
 | |
| 		} catch (NoSuchFileException var11) {
 | |
| 			return false;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	static {
 | |
| 		byte[] bs = "☃".getBytes(Charsets.UTF_8);
 | |
| 		DUMMY = ByteBuffer.allocateDirect(bs.length);
 | |
| 		DUMMY.put(bs);
 | |
| 		DUMMY.flip();
 | |
| 	}
 | |
| 
 | |
| 	public static class LockException extends IOException {
 | |
| 		private LockException(Path path, String message) {
 | |
| 			super(path.toAbsolutePath() + ": " + message);
 | |
| 		}
 | |
| 
 | |
| 		public static DirectoryLock.LockException alreadyLocked(Path path) {
 | |
| 			return new DirectoryLock.LockException(path, "already locked (possibly by other Minecraft instance?)");
 | |
| 		}
 | |
| 	}
 | |
| }
 |