LUCENE-1048: fix Lock.obtain(...) to work properly on very large timeouts, eg Long.MAX_VALUE

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@593774 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2007-11-10 13:43:18 +00:00
parent a98a30818f
commit f69f98c0e4
2 changed files with 27 additions and 7 deletions

View File

@ -139,6 +139,11 @@ Bug fixes
DisjunctionMaxQuery, ValueSourceQuery, CustomScoreQuery. DisjunctionMaxQuery, ValueSourceQuery, CustomScoreQuery.
Serialization check added for all queries. Serialization check added for all queries.
(Kyle Maxwell via Doron Cohen) (Kyle Maxwell via Doron Cohen)
22. LUCENE-1048: Fixed incorrect behavior in Lock.obtain(...) when the
timeout argument is very large (eg Long.MAX_VALUE). Also added
Lock.LOCK_OBTAIN_WAIT_FOREVER constant to never timeout. (Nikolay
Diakov via Mike McCandless)
New features New features

View File

@ -33,8 +33,15 @@ import java.io.IOException;
* @see Directory#makeLock(String) * @see Directory#makeLock(String)
*/ */
public abstract class Lock { public abstract class Lock {
/** How long {@link #obtain(long)} waits, in milliseconds,
* in between attempts to acquire the lock. */
public static long LOCK_POLL_INTERVAL = 1000; public static long LOCK_POLL_INTERVAL = 1000;
/** Pass this value to {@link #obtain(long)} to try
* forever to obtain the lock. */
public static final long LOCK_OBTAIN_WAIT_FOREVER = -1;
/** Attempts to obtain exclusive access and immediately return /** Attempts to obtain exclusive access and immediately return
* upon success or failure. * upon success or failure.
* @return true iff exclusive access is obtained * @return true iff exclusive access is obtained
@ -48,21 +55,29 @@ public abstract class Lock {
*/ */
protected Throwable failureReason; protected Throwable failureReason;
/** Attempts to obtain an exclusive lock within amount /** Attempts to obtain an exclusive lock within amount of
* of time given. Currently polls once per second until * time given. Polls once per {@link #LOCK_POLL_INTERVAL}
* lockWaitTimeout is passed. * (currently 1000) milliseconds until lockWaitTimeout is
* @param lockWaitTimeout length of time to wait in ms * passed.
* @param lockWaitTimeout length of time to wait in
* milliseconds or {@link
* #LOCK_OBTAIN_WAIT_FOREVER} to retry forever
* @return true if lock was obtained * @return true if lock was obtained
* @throws LockObtainFailedException if lock wait times out * @throws LockObtainFailedException if lock wait times out
* @throws IllegalArgumentException if lockWaitTimeout is
* out of bounds
* @throws IOException if obtain() throws IOException * @throws IOException if obtain() throws IOException
*/ */
public boolean obtain(long lockWaitTimeout) throws LockObtainFailedException, IOException { public boolean obtain(long lockWaitTimeout) throws LockObtainFailedException, IOException {
failureReason = null; failureReason = null;
boolean locked = obtain(); boolean locked = obtain();
int maxSleepCount = (int)(lockWaitTimeout / LOCK_POLL_INTERVAL); if (lockWaitTimeout < 0 && lockWaitTimeout != LOCK_OBTAIN_WAIT_FOREVER)
int sleepCount = 0; throw new IllegalArgumentException("lockWaitTimeout should be LOCK_OBTAIN_WAIT_FOREVER or a non-negative number (got " + lockWaitTimeout + ")");
long maxSleepCount = lockWaitTimeout / LOCK_POLL_INTERVAL;
long sleepCount = 0;
while (!locked) { while (!locked) {
if (sleepCount++ == maxSleepCount) { if (lockWaitTimeout != LOCK_OBTAIN_WAIT_FOREVER && sleepCount++ >= maxSleepCount) {
String reason = "Lock obtain timed out: " + this.toString(); String reason = "Lock obtain timed out: " + this.toString();
if (failureReason != null) { if (failureReason != null) {
reason += ": " + failureReason; reason += ": " + failureReason;