/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using IndexWriter = Lucene.Net.Index.IndexWriter;
namespace Lucene.Net.Store
{
/// An interprocess mutex lock.
///
Typical use might look like:
/// new Lock.With(directory.makeLock("my.lock")) {
/// public Object doBody() {
/// ... code to execute while locked ...
/// }
/// }.Run();
///
///
///
/// Doug Cutting
///
/// $Id: Lock.java 179414 2005-06-01 20:10:58Z dnaber $
///
///
///
public abstract class Lock
{
public static long LOCK_POLL_INTERVAL = 1000;
/// Attempts to obtain exclusive access and immediately return
/// upon success or failure.
///
/// true iff exclusive access is obtained
///
public abstract bool Obtain();
/// Attempts to obtain an exclusive lock within amount
/// of time given. Currently polls once per second until
/// lockWaitTimeout is passed.
///
/// length of time to wait in ms
///
/// true if lock was obtained
///
/// IOException if lock wait times out or obtain() throws an IOException
public virtual bool Obtain(long lockWaitTimeout)
{
bool locked = Obtain();
int maxSleepCount = (int) (lockWaitTimeout / LOCK_POLL_INTERVAL);
int sleepCount = 0;
while (!locked)
{
if (sleepCount++ == maxSleepCount)
{
throw new System.IO.IOException("Lock obtain timed out: " + this.ToString());
}
try
{
System.Threading.Thread.Sleep(new System.TimeSpan((System.Int64) 10000 * LOCK_POLL_INTERVAL));
}
catch (System.Threading.ThreadInterruptedException e)
{
throw new System.IO.IOException(e.ToString());
}
locked = Obtain();
}
return locked;
}
/// Releases exclusive access.
public abstract void Release();
/// Returns true if the resource is currently locked. Note that one must
/// still call {@link #Obtain()} before using the resource.
///
public abstract bool IsLocked();
/// Utility class for executing code with exclusive access.
public abstract class With
{
private Lock lock_Renamed;
private long lockWaitTimeout;
/// Constructs an executor that will grab the named lock.
public With(Lock lock_Renamed, long lockWaitTimeout)
{
this.lock_Renamed = lock_Renamed;
this.lockWaitTimeout = lockWaitTimeout;
}
/// Code to execute with exclusive access.
public abstract System.Object DoBody();
/// Calls {@link #doBody} while lock is obtained. Blocks if lock
/// cannot be obtained immediately. Retries to obtain lock once per second
/// until it is obtained, or until it has tried ten times. Lock is released when
/// {@link #doBody} exits.
///
public virtual System.Object Run()
{
bool locked = false;
try
{
locked = lock_Renamed.Obtain(lockWaitTimeout);
return DoBody();
}
finally
{
if (locked)
lock_Renamed.Release();
}
}
}
}
}