001: /*
002: * ====================================================================
003: * Copyright (c) 2004-2008 TMate Software Ltd. All rights reserved.
004: *
005: * This software is licensed as described in the file COPYING, which
006: * you should have received as part of this distribution. The terms
007: * are also available at http://svnkit.com/license.html
008: * If newer versions of this license are posted there, you may use a
009: * newer version instead, at your option.
010: * ====================================================================
011: */
012: package org.tmatesoft.svn.core.internal.io.fs;
013:
014: import java.io.IOException;
015: import java.io.RandomAccessFile;
016: import java.nio.channels.FileLock;
017: import java.io.File;
018: import java.util.HashMap;
019: import java.util.Map;
020:
021: import org.tmatesoft.svn.core.internal.wc.SVNFileType;
022: import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
023: import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
024: import org.tmatesoft.svn.core.SVNException;
025: import org.tmatesoft.svn.core.SVNErrorMessage;
026: import org.tmatesoft.svn.core.SVNErrorCode;
027:
028: /**
029: * @version 1.1.1
030: * @author TMate Software Ltd.
031: */
032: public class FSWriteLock {
033:
034: private static final Map ourThreadLocksCache = new HashMap();
035:
036: private RandomAccessFile myLockFile;
037: private FileLock myLock;
038: private int myReferencesCount = 0;
039: private FSFS myFSFS;
040: private String myUUID;
041:
042: private FSWriteLock(String uuid, FSFS owner) {
043: myUUID = uuid;
044: myFSFS = owner;
045: }
046:
047: public static synchronized FSWriteLock getWriteLock(FSFS owner)
048: throws SVNException {
049: String uuid = owner.getUUID();
050: FSWriteLock lock = (FSWriteLock) ourThreadLocksCache.get(uuid);
051:
052: if (lock == null) {
053: lock = new FSWriteLock(uuid, owner);
054: ourThreadLocksCache.put(uuid, lock);
055: }
056: lock.myReferencesCount++;
057: return lock;
058: }
059:
060: public synchronized void lock() throws SVNException {
061: File writeLockFile = myFSFS.getWriteLockFile();
062:
063: try {
064: SVNFileType type = SVNFileType.getType(writeLockFile);
065: if (type == SVNFileType.UNKNOWN || type == SVNFileType.NONE) {
066: SVNFileUtil.createEmptyFile(writeLockFile);
067: }
068:
069: myLockFile = new RandomAccessFile(writeLockFile, "rw");
070: myLock = myLockFile.getChannel().lock();
071: } catch (IOException ioe) {
072: unlock();
073: SVNErrorMessage err = SVNErrorMessage.create(
074: SVNErrorCode.IO_ERROR,
075: "Can't get exclusive lock on file ''{0}'': {1}",
076: new Object[] { writeLockFile,
077: ioe.getLocalizedMessage() });
078: SVNErrorManager.error(err, ioe);
079: }
080: }
081:
082: public static synchronized void realease(FSWriteLock lock) {
083: if (lock == null) {
084: return;
085: }
086: if ((--lock.myReferencesCount) == 0) {
087: ourThreadLocksCache.remove(lock.myUUID);
088: }
089: }
090:
091: public synchronized void unlock() {
092: if (myLock != null) {
093: try {
094: myLock.release();
095: } catch (IOException ioex) {
096: //
097: }
098: myLock = null;
099: }
100: SVNFileUtil.closeFile(myLockFile);
101: myLockFile = null;
102: }
103: }
|