Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/Lucene.Net.Light.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/Store/Lock.cs')
-rw-r--r--src/core/Store/Lock.cs163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/core/Store/Lock.cs b/src/core/Store/Lock.cs
new file mode 100644
index 0000000..9c30012
--- /dev/null
+++ b/src/core/Store/Lock.cs
@@ -0,0 +1,163 @@
+/*
+ * 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 Lucene.Net.Support;
+
+namespace Lucene.Net.Store
+{
+
+ /// <summary>An interprocess mutex lock.
+ /// <p/>Typical use might look like:<code>
+ /// new Lock.With(directory.makeLock("my.lock")) {
+ /// public Object doBody() {
+ /// <i>... code to execute while locked ...</i>
+ /// }
+ /// }.run();
+ /// </code>
+ /// </summary>
+ /// <seealso cref="Directory.MakeLock(String)" />
+ public abstract class Lock
+ {
+
+ /// <summary>How long <see cref="Obtain(long)" /> waits, in milliseconds,
+ /// in between attempts to acquire the lock.
+ /// </summary>
+ public static long LOCK_POLL_INTERVAL = 1000;
+
+ /// <summary>Pass this value to <see cref="Obtain(long)" /> to try
+ /// forever to obtain the lock.
+ /// </summary>
+ public const long LOCK_OBTAIN_WAIT_FOREVER = - 1;
+
+ /// <summary>Attempts to obtain exclusive access and immediately return
+ /// upon success or failure.
+ /// </summary>
+ /// <returns> true iff exclusive access is obtained
+ /// </returns>
+ public abstract bool Obtain();
+
+ /// <summary> If a lock obtain called, this failureReason may be set
+ /// with the "root cause" Exception as to why the lock was
+ /// not obtained.
+ /// </summary>
+ protected internal System.Exception failureReason;
+
+ /// <summary>Attempts to obtain an exclusive lock within amount of
+ /// time given. Polls once per <see cref="LOCK_POLL_INTERVAL" />
+ /// (currently 1000) milliseconds until lockWaitTimeout is
+ /// passed.
+ /// </summary>
+ /// <param name="lockWaitTimeout">length of time to wait in
+ /// milliseconds or <see cref="LOCK_OBTAIN_WAIT_FOREVER" />
+ /// to retry forever
+ /// </param>
+ /// <returns> true if lock was obtained
+ /// </returns>
+ /// <throws> LockObtainFailedException if lock wait times out </throws>
+ /// <throws> IllegalArgumentException if lockWaitTimeout is </throws>
+ /// <summary> out of bounds
+ /// </summary>
+ /// <throws> IOException if obtain() throws IOException </throws>
+ public virtual bool Obtain(long lockWaitTimeout)
+ {
+ failureReason = null;
+ bool locked = Obtain();
+ if (lockWaitTimeout < 0 && lockWaitTimeout != LOCK_OBTAIN_WAIT_FOREVER)
+ throw new System.ArgumentException("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)
+ {
+ if (lockWaitTimeout != LOCK_OBTAIN_WAIT_FOREVER && sleepCount++ >= maxSleepCount)
+ {
+ System.String reason = "Lock obtain timed out: " + this.ToString();
+ if (failureReason != null)
+ {
+ reason += (": " + failureReason);
+ }
+ var e = failureReason != null
+ ? new LockObtainFailedException(reason, failureReason)
+ : new LockObtainFailedException(reason);
+ throw e;
+ }
+ try
+ {
+ System.Threading.Thread.Sleep(TimeSpan.FromMilliseconds(LOCK_POLL_INTERVAL));
+ }
+ catch (System.Threading.ThreadInterruptedException)
+ {
+ throw;
+ }
+ locked = Obtain();
+ }
+ return locked;
+ }
+
+ /// <summary>Releases exclusive access. </summary>
+ public abstract void Release();
+
+ /// <summary>Returns true if the resource is currently locked. Note that one must
+ /// still call <see cref="Obtain()" /> before using the resource.
+ /// </summary>
+ public abstract bool IsLocked();
+
+
+ /// <summary>Utility class for executing code with exclusive access. </summary>
+ public abstract class With
+ {
+ private Lock lock_Renamed;
+ private long lockWaitTimeout;
+
+
+ /// <summary>Constructs an executor that will grab the named lock. </summary>
+ protected With(Lock lock_Renamed, long lockWaitTimeout)
+ {
+ this.lock_Renamed = lock_Renamed;
+ this.lockWaitTimeout = lockWaitTimeout;
+ }
+
+ /// <summary>Code to execute with exclusive access. </summary>
+ protected internal abstract System.Object DoBody();
+
+ /// <summary>Calls <see cref="DoBody" /> while <i>lock</i> 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
+ /// <see cref="DoBody" /> exits.
+ /// </summary>
+ /// <throws> LockObtainFailedException if lock could not </throws>
+ /// <summary> be obtained
+ /// </summary>
+ /// <throws> IOException if <see cref="Lock.Obtain(long)" /> throws IOException </throws>
+ public virtual System.Object run()
+ {
+ bool locked = false;
+ try
+ {
+ locked = lock_Renamed.Obtain(lockWaitTimeout);
+ return DoBody();
+ }
+ finally
+ {
+ if (locked)
+ lock_Renamed.Release();
+ }
+ }
+ }
+ }
+} \ No newline at end of file