comparison src/org/tmatesoft/hg/repo/HgRepositoryLock.java @ 489:9c0138cda59a

HgRepositoryLock: some javadoc
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Mon, 13 Aug 2012 19:24:29 +0200
parents 45b3b6ca046f
children 3cd3c3d37432
comparison
equal deleted inserted replaced
488:45b3b6ca046f 489:9c0138cda59a
23 import java.lang.management.ManagementFactory; 23 import java.lang.management.ManagementFactory;
24 import java.net.InetAddress; 24 import java.net.InetAddress;
25 import java.nio.ByteBuffer; 25 import java.nio.ByteBuffer;
26 import java.nio.channels.FileChannel; 26 import java.nio.channels.FileChannel;
27 27
28 import org.tmatesoft.hg.internal.Experimental;
28 import org.tmatesoft.hg.internal.Internals; 29 import org.tmatesoft.hg.internal.Internals;
29 30
30 /** 31 /**
31 * NOT SAFE FOR MULTITHREAD USE! 32 * NOT SAFE FOR MULTITHREAD USE!
32 * 33 *
34 * <p>Usage:
35 * <pre>
36 * HgRepositoryLock lock = hgRepo.getWorkingDirLock();
37 * try {
38 * // Actually lock the repo
39 * lock.acquire();
40 * ///
41 * // do whatever modifies working directory
42 * ...
43 * } finally {
44 * if (lock.isLocked()) {
45 * // this check is needed not to release()
46 * // erroneously in case acquire() failed (e.g. due to timeout)
47 * lock.release();
48 * }
49 *
50 * </pre>
51 *
33 * Unlike original mechanism, we don't use symlinks, rather files, as it's easier to implement 52 * Unlike original mechanism, we don't use symlinks, rather files, as it's easier to implement
34 * 53 *
54 * @see http://code.google.com/p/hg4j/issues/detail?id=35
35 * @author Artem Tikhomirov 55 * @author Artem Tikhomirov
36 * @author TMate Software Ltd. 56 * @author TMate Software Ltd.
37 */ 57 */
58 @Experimental(reason="Work in progress")
38 public class HgRepositoryLock { 59 public class HgRepositoryLock {
39 /* 60 /*
40 * Lock .hg/ except .hg/store/ .hg/wlock (new File(hgRepo.getRepoRoot(),"wlock")) 61 * Lock .hg/ except .hg/store/ .hg/wlock (new File(hgRepo.getRepoRoot(),"wlock"))
41 * Lock .hg/store/ .hg/store/lock (HgRepository.repoPathHelper("lock")) 62 * Lock .hg/store/ .hg/store/lock (HgRepository.repoPathHelper("lock"))
42 */ 63 */
66 } 87 }
67 } 88 }
68 return null; 89 return null;
69 } 90 }
70 91
92 /**
93 * @return <code>true</code> if we hold the lock
94 */
71 public boolean isLocked() { 95 public boolean isLocked() {
72 return use > 0; 96 return use > 0;
73 } 97 }
74 98
99 /**
100 * Perform actual locking. Waits for timeout (if specified at construction time)
101 * before throwing {@link HgInvalidStateException} in case lock is not available
102 * immediately.
103 *
104 * <p>Multiple calls are possible, but corresponding number of {@link #release()}
105 * calls shall be made.
106 */
75 public void acquire() { 107 public void acquire() {
76 if (use > 0) { 108 if (use > 0) {
77 use++; 109 use++;
78 return; 110 return;
79 } 111 }
104 } while (stopTime == -1/*no timeout*/ || System.currentTimeMillis() <= stopTime); 136 } while (stopTime == -1/*no timeout*/ || System.currentTimeMillis() <= stopTime);
105 String msg = String.format("Failed to aquire lock, waited for %d seconds, present owner: '%s'", timeoutSeconds, readLockInfo()); 137 String msg = String.format("Failed to aquire lock, waited for %d seconds, present owner: '%s'", timeoutSeconds, readLockInfo());
106 throw new HgInvalidStateException(msg); 138 throw new HgInvalidStateException(msg);
107 } 139 }
108 140
141 /**
142 * Release lock we own
143 */
109 public void release() { 144 public void release() {
110 if (use == 0) { 145 if (use == 0) {
111 throw new HgInvalidStateException(""); 146 throw new HgInvalidStateException("Lock is not held!");
112 } 147 }
113 use--; 148 use--;
114 if (use > 0) { 149 if (use > 0) {
115 return; 150 return;
116 } 151 }