2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
20 namespace Mono.Lucene.Net.Store
23 /// <summary> <p/>Implements {@link LockFactory} using {@link
24 /// File#createNewFile()}.<p/>
26 /// <p/><b>NOTE:</b> the <a target="_top"
27 /// href="http://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html#createNewFile()">javadocs
28 /// for <code>File.createNewFile</code></a> contain a vague
29 /// yet spooky warning about not using the API for file
30 /// locking. This warning was added due to <a target="_top"
31 /// href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4676183">this
32 /// bug</a>, and in fact the only known problem with using
33 /// this API for locking is that the Lucene write lock may
34 /// not be released when the JVM exits abnormally.<p/>
35 /// <p/>When this happens, a {@link LockObtainFailedException}
36 /// is hit when trying to create a writer, in which case you
37 /// need to explicitly clear the lock file first. You can
38 /// either manually remove the file, or use the {@link
39 /// org.apache.lucene.index.IndexReader#unlock(Directory)}
40 /// API. But, first be certain that no writer is in fact
41 /// writing to the index otherwise you can easily corrupt
44 /// <p/>If you suspect that this or any other LockFactory is
45 /// not working properly in your environment, you can easily
46 /// test it by using {@link VerifyingLockFactory}, {@link
47 /// LockVerifyServer} and {@link LockStressTest}.<p/>
50 /// <seealso cref="LockFactory">
53 public class SimpleFSLockFactory:FSLockFactory
56 /// <summary> Create a SimpleFSLockFactory instance, with null (unset)
57 /// lock directory. When you pass this factory to a {@link FSDirectory}
58 /// subclass, the lock directory is automatically set to the
59 /// directory itsself. Be sure to create one instance for each directory
62 public SimpleFSLockFactory():this((System.IO.DirectoryInfo) null)
66 /// <summary> Instantiate using the provided directory (as a File instance).</summary>
67 /// <param name="lockDir">where lock files should be created.
69 [System.Obsolete("Use the constructor that takes a DirectoryInfo, this will be removed in the 3.0 release")]
70 public SimpleFSLockFactory(System.IO.FileInfo lockDir)
72 SetLockDir(new System.IO.DirectoryInfo(lockDir.FullName));
75 /// <summary> Instantiate using the provided directory (as a File instance).</summary>
76 /// <param name="lockDir">where lock files should be created.
78 public SimpleFSLockFactory(System.IO.DirectoryInfo lockDir)
83 /// <summary> Instantiate using the provided directory name (String).</summary>
84 /// <param name="lockDirName">where lock files should be created.
86 public SimpleFSLockFactory(System.String lockDirName)
88 lockDir = new System.IO.DirectoryInfo(lockDirName);
92 public override Lock MakeLock(System.String lockName)
94 if (lockPrefix != null)
96 lockName = lockPrefix + "-" + lockName;
98 return new SimpleFSLock(lockDir, lockName);
101 public override void ClearLock(System.String lockName)
104 if (System.IO.File.Exists(lockDir.FullName))
107 tmpBool = System.IO.Directory.Exists(lockDir.FullName);
110 if (lockPrefix != null)
112 lockName = lockPrefix + "-" + lockName;
114 System.IO.FileInfo lockFile = new System.IO.FileInfo(System.IO.Path.Combine(lockDir.FullName, lockName));
116 if (System.IO.File.Exists(lockFile.FullName))
119 tmpBool2 = System.IO.Directory.Exists(lockFile.FullName);
121 if (System.IO.File.Exists(lockFile.FullName))
123 System.IO.File.Delete(lockFile.FullName);
126 else if (System.IO.Directory.Exists(lockFile.FullName))
128 System.IO.Directory.Delete(lockFile.FullName);
133 if (tmpBool2 && !tmpBool3)
135 throw new System.IO.IOException("Cannot delete " + lockFile);
142 class SimpleFSLock:Lock
145 internal System.IO.FileInfo lockFile;
146 internal System.IO.DirectoryInfo lockDir;
148 [System.Obsolete("Use the constructor that takes a DirectoryInfo, this will be removed in the 3.0 release")]
149 public SimpleFSLock(System.IO.FileInfo lockDir, System.String lockFileName) : this(new System.IO.DirectoryInfo(lockDir.FullName), lockFileName)
153 public SimpleFSLock(System.IO.DirectoryInfo lockDir, System.String lockFileName)
155 this.lockDir = new System.IO.DirectoryInfo(lockDir.FullName);
156 lockFile = new System.IO.FileInfo(System.IO.Path.Combine(lockDir.FullName, lockFileName));
159 public override bool Obtain()
162 // Ensure that lockDir exists and is a directory:
164 if (System.IO.File.Exists(lockDir.FullName))
167 tmpBool = System.IO.Directory.Exists(lockDir.FullName);
172 System.IO.Directory.CreateDirectory(lockDir.FullName);
176 throw new System.IO.IOException("Cannot create directory: " + lockDir.FullName);
183 System.IO.Directory.Exists(lockDir.FullName);
187 throw new System.IO.IOException("Found regular file where directory expected: " + lockDir.FullName);
197 System.IO.FileStream createdFile = lockFile.Create();
203 public override void Release()
206 if (System.IO.File.Exists(lockFile.FullName))
209 tmpBool = System.IO.Directory.Exists(lockFile.FullName);
211 if (System.IO.File.Exists(lockFile.FullName))
213 System.IO.File.Delete(lockFile.FullName);
216 else if (System.IO.Directory.Exists(lockFile.FullName))
218 System.IO.Directory.Delete(lockFile.FullName);
223 if (tmpBool && !tmpBool2)
224 throw new LockReleaseFailedException("failed to delete " + lockFile);
227 public override bool IsLocked()
230 if (System.IO.File.Exists(lockFile.FullName))
233 tmpBool = System.IO.Directory.Exists(lockFile.FullName);
237 public override System.String ToString()
239 return "SimpleFSLock@" + lockFile;