Lucene.Net  3.0.3
Lucene.Net is a port of the Lucene search engine library, written in C# and targeted at .NET runtime users.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
SimpleFSLockFactory.cs
Go to the documentation of this file.
1 /*
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
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  */
17 
18 using System;
19 
20 namespace Lucene.Net.Store
21 {
22 
23  /// <summary> <p/>Implements <see cref="LockFactory" /> using <see cref="System.IO.FileInfo.Create()" />
24  ///.<p/>
25  ///
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 <c>File.createNewFile</c></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 <see cref="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
39  /// <see cref="Lucene.Net.Index.IndexWriter.Unlock(Directory)" />
40  /// API. But, first be certain that no writer is in fact
41  /// writing to the index otherwise you can easily corrupt
42  /// your index.<p/>
43  ///
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 <see cref="VerifyingLockFactory" />, <see cref="LockVerifyServer" />
47  /// and <see cref="LockStressTest" />.<p/>
48  ///
49  /// </summary>
50  /// <seealso cref="LockFactory">
51  /// </seealso>
52 
54  {
55 
56  /// <summary> Create a SimpleFSLockFactory instance, with null (unset)
57  /// lock directory. When you pass this factory to a <see cref="FSDirectory" />
58  /// subclass, the lock directory is automatically set to the
59  /// directory itsself. Be sure to create one instance for each directory
60  /// your create!
61  /// </summary>
62  public SimpleFSLockFactory():this((System.IO.DirectoryInfo) null)
63  {
64  }
65 
66  /// <summary> Instantiate using the provided directory (as a File instance).</summary>
67  /// <param name="lockDir">where lock files should be created.
68  /// </param>
69  public SimpleFSLockFactory(System.IO.DirectoryInfo lockDir)
70  {
71  LockDir = lockDir;
72  }
73 
74  /// <summary> Instantiate using the provided directory name (String).</summary>
75  /// <param name="lockDirName">where lock files should be created.
76  /// </param>
77  public SimpleFSLockFactory(System.String lockDirName)
78  : this(new System.IO.DirectoryInfo(lockDirName))
79  {
80  }
81 
82  public override Lock MakeLock(System.String lockName)
83  {
84  if (internalLockPrefix != null)
85  {
86  lockName = internalLockPrefix + "-" + lockName;
87  }
88  return new SimpleFSLock(internalLockDir, lockName);
89  }
90 
91  public override void ClearLock(System.String lockName)
92  {
93  bool tmpBool;
94  if (System.IO.File.Exists(internalLockDir.FullName))
95  tmpBool = true;
96  else
97  tmpBool = System.IO.Directory.Exists(internalLockDir.FullName);
98  if (tmpBool)
99  {
100  if (internalLockPrefix != null)
101  {
102  lockName = internalLockPrefix + "-" + lockName;
103  }
104  System.IO.FileInfo lockFile = new System.IO.FileInfo(System.IO.Path.Combine(internalLockDir.FullName, lockName));
105  bool tmpBool2;
106  if (System.IO.File.Exists(lockFile.FullName))
107  tmpBool2 = true;
108  else
109  tmpBool2 = System.IO.Directory.Exists(lockFile.FullName);
110  bool tmpBool3;
111  if (System.IO.File.Exists(lockFile.FullName))
112  {
113  System.IO.File.Delete(lockFile.FullName);
114  tmpBool3 = true;
115  }
116  else if (System.IO.Directory.Exists(lockFile.FullName))
117  {
118  System.IO.Directory.Delete(lockFile.FullName);
119  tmpBool3 = true;
120  }
121  else
122  tmpBool3 = false;
123  if (tmpBool2 && !tmpBool3)
124  {
125  throw new System.IO.IOException("Cannot delete " + lockFile);
126  }
127  }
128  }
129  }
130 
131 
133  {
134 
135  internal System.IO.FileInfo lockFile;
136  internal System.IO.DirectoryInfo lockDir;
137 
138  [System.Obsolete("Use the constructor that takes a DirectoryInfo, this will be removed in the 3.0 release")]
139  public SimpleFSLock(System.IO.FileInfo lockDir, System.String lockFileName) : this(new System.IO.DirectoryInfo(lockDir.FullName), lockFileName)
140  {
141  }
142 
143  public SimpleFSLock(System.IO.DirectoryInfo lockDir, System.String lockFileName)
144  {
145  this.lockDir = new System.IO.DirectoryInfo(lockDir.FullName);
146  lockFile = new System.IO.FileInfo(System.IO.Path.Combine(lockDir.FullName, lockFileName));
147  }
148 
149  public override bool Obtain()
150  {
151 
152  // Ensure that lockDir exists and is a directory:
153  bool tmpBool;
154  if (System.IO.File.Exists(lockDir.FullName))
155  tmpBool = true;
156  else
157  tmpBool = System.IO.Directory.Exists(lockDir.FullName);
158  if (!tmpBool)
159  {
160  try
161  {
162  System.IO.Directory.CreateDirectory(lockDir.FullName);
163  }
164  catch
165  {
166  throw new System.IO.IOException("Cannot create directory: " + lockDir.FullName);
167  }
168  }
169  else
170  {
171  try
172  {
173  System.IO.Directory.Exists(lockDir.FullName);
174  }
175  catch
176  {
177  throw new System.IO.IOException("Found regular file where directory expected: " + lockDir.FullName);
178  }
179  }
180 
181  if (lockFile.Exists)
182  {
183  return false;
184  }
185  else
186  {
187  System.IO.FileStream createdFile = lockFile.Create();
188  createdFile.Close();
189  return true;
190  }
191  }
192 
193  public override void Release()
194  {
195  bool tmpBool;
196  if (System.IO.File.Exists(lockFile.FullName))
197  tmpBool = true;
198  else
199  tmpBool = System.IO.Directory.Exists(lockFile.FullName);
200  bool tmpBool2;
201  if (System.IO.File.Exists(lockFile.FullName))
202  {
203  System.IO.File.Delete(lockFile.FullName);
204  tmpBool2 = true;
205  }
206  else if (System.IO.Directory.Exists(lockFile.FullName))
207  {
208  System.IO.Directory.Delete(lockFile.FullName);
209  tmpBool2 = true;
210  }
211  else
212  tmpBool2 = false;
213  if (tmpBool && !tmpBool2)
214  throw new LockReleaseFailedException("failed to delete " + lockFile);
215  }
216 
217  public override bool IsLocked()
218  {
219  bool tmpBool;
220  if (System.IO.File.Exists(lockFile.FullName))
221  tmpBool = true;
222  else
223  tmpBool = System.IO.Directory.Exists(lockFile.FullName);
224  return tmpBool;
225  }
226 
227  public override System.String ToString()
228  {
229  return "SimpleFSLock@" + lockFile;
230  }
231  }
232 }