001 package gate.creole.annic.apache.lucene.store;
002
003 /**
004 * Copyright 2004 The Apache Software Foundation
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 import gate.creole.annic.apache.lucene.index.IndexWriter;
020
021 import java.io.IOException;
022
023 /** An interprocess mutex lock.
024 * <p>Typical use might look like:<pre>
025 * new Lock.With(directory.makeLock("my.lock")) {
026 * public Object doBody() {
027 * <i>... code to execute while locked ...</i>
028 * }
029 * }.run();
030 * </pre>
031 *
032 * @author Doug Cutting
033 * @version $Id: Lock.java 529 2004-10-05 11:55:26Z niraj $
034 * @see Directory#makeLock(String)
035 */
036 public abstract class Lock {
037 public static long LOCK_POLL_INTERVAL = 1000;
038
039 /** Attempts to obtain exclusive access and immediately return
040 * upon success or failure.
041 * @return true iff exclusive access is obtained
042 */
043 public abstract boolean obtain() throws IOException;
044
045 /** Attempts to obtain an exclusive lock within amount
046 * of time given. Currently polls once per second until
047 * lockWaitTimeout is passed.
048 * @param lockWaitTimeout length of time to wait in ms
049 * @return true if lock was obtained
050 * @throws IOException if lock wait times out or obtain() throws an IOException
051 */
052 public boolean obtain(long lockWaitTimeout) throws IOException {
053 boolean locked = obtain();
054 int maxSleepCount = (int)(lockWaitTimeout / LOCK_POLL_INTERVAL);
055 int sleepCount = 0;
056 while (!locked) {
057 if (++sleepCount == maxSleepCount) {
058 throw new IOException("Lock obtain timed out: " + this.toString());
059 }
060 try {
061 Thread.sleep(LOCK_POLL_INTERVAL);
062 } catch (InterruptedException e) {
063 throw new IOException(e.toString());
064 }
065 locked = obtain();
066 }
067 return locked;
068 }
069
070 /** Releases exclusive access. */
071 public abstract void release();
072
073 /** Returns true if the resource is currently locked. Note that one must
074 * still call {@link #obtain()} before using the resource. */
075 public abstract boolean isLocked();
076
077
078 /** Utility class for executing code with exclusive access. */
079 public abstract static class With {
080 private Lock lock;
081 private long lockWaitTimeout;
082
083 /** Constructs an executor that will grab the named lock.
084 * Defaults lockWaitTimeout to Lock.COMMIT_LOCK_TIMEOUT.
085 * @deprecated Kept only to avoid breaking existing code.
086 */
087 public With(Lock lock)
088 {
089 this(lock, IndexWriter.COMMIT_LOCK_TIMEOUT);
090 }
091
092 /** Constructs an executor that will grab the named lock. */
093 public With(Lock lock, long lockWaitTimeout) {
094 this.lock = lock;
095 this.lockWaitTimeout = lockWaitTimeout;
096 }
097
098 /** Code to execute with exclusive access. */
099 protected abstract Object doBody() throws IOException;
100
101 /** Calls {@link #doBody} while <i>lock</i> is obtained. Blocks if lock
102 * cannot be obtained immediately. Retries to obtain lock once per second
103 * until it is obtained, or until it has tried ten times. Lock is released when
104 * {@link #doBody} exits. */
105 public Object run() throws IOException {
106 boolean locked = false;
107 try {
108 locked = lock.obtain(lockWaitTimeout);
109 return doBody();
110 } finally {
111 if (locked)
112 lock.release();
113 }
114 }
115 }
116
117 }
|