1 From: Debajyoti Bera <dbera.web@gmail.com>
3 Lucene uses lockfiles for sharing index files across multiple processes. Stock lucene.net implementation creates the lockfile incorrectly. 01_obtain-lock-fix.patch fixes that but leaves a small race window. This patch removes the race window. It uses native open() syscall instead of System.IO File operations as the mono implementations for File.Open() turned out to be buggy (giving wrong sharing violation errors).
5 Index: Store/FSDirectory.cs
6 ===================================================================
7 RCS file: /cvs/gnome/beagle/beagled/Lucene.Net/Store/FSDirectory.cs,v
8 retrieving revision 1.15
9 diff -u -3 -p -r1.15 FSDirectory.cs
10 --- Store/FSDirectory.cs 13 Mar 2006 21:45:34 -0000 1.15
11 +++ Store/FSDirectory.cs 23 Mar 2006 13:50:28 -0000
13 * limitations under the License.
16 +using Mono.Unix.Native;
17 using Constants = Lucene.Net.Util.Constants;
18 namespace Lucene.Net.Store
20 @@ -52,6 +53,7 @@ namespace Lucene.Net.Store
22 public override bool Obtain()
24 + Log ("Trying to obtain lock " + lockFile.FullName);
25 if (Lucene.Net.Store.FSDirectory.DISABLE_LOCKS || Enclosing_Instance.DisableLocks)
28 @@ -62,36 +64,45 @@ namespace Lucene.Net.Store
29 tmpBool = System.IO.Directory.Exists(Enclosing_Instance.lockDir.FullName);
34 - System.IO.Directory.CreateDirectory(Enclosing_Instance.lockDir.FullName);
39 + System.IO.Directory.CreateDirectory(Enclosing_Instance.lockDir.FullName);
43 throw new System.IO.IOException("Cannot create lock directory: " + Enclosing_Instance.lockDir);
47 - bool obtainedLock = false;
49 - if (! System.IO.File.Exists(lockFile.FullName)) {
52 - System.IO.FileStream createdFile = lockFile.Create();
53 - System.IO.StreamWriter writer = new System.IO.StreamWriter (createdFile);
54 - writer.WriteLine (System.Diagnostics.Process.GetCurrentProcess().Id);
56 - createdFile.Close();
57 - obtainedLock = true;
66 + int fd = Mono.Unix.Native.Syscall.open (
68 + Mono.Unix.Native.OpenFlags.O_RDWR |
69 + Mono.Unix.Native.OpenFlags.O_CREAT |
70 + Mono.Unix.Native.OpenFlags.O_EXCL,
71 + Mono.Unix.Native.FilePermissions.S_IRUSR);
73 + throw new System.IO.IOException ("Could not create lock file: "
74 + + Mono.Unix.Native.Stdlib.strerror (
75 + Mono.Unix.Native.Stdlib.GetLastError ()
77 + int ret = Mono.Unix.Native.Syscall.close (fd);
79 + throw new System.IO.IOException ("Could not close lock file: "
80 + + Mono.Unix.Native.Stdlib.strerror (
81 + Mono.Unix.Native.Stdlib.GetLastError ()
83 + // FIXME: Should the file be cleaned up if we can open it but not close it ?
85 - Log ("{0} lock {1}", obtainedLock ? "Obtained" : "Could not obtain", lockFile.FullName);
86 - return obtainedLock;
87 + Log ("Obtained lock " + lockFile.FullName);
92 + Log ("Exception in CreateNew for file:" + lockFile.FullName + ":" + e);
96 public override void Release()
98 @@ -110,6 +121,10 @@ namespace Lucene.Net.Store
102 + if (System.IO.File.Exists(lockFile.FullName)) {
103 + Log ("Release didnt delete lockfile {0}.", lockFile.FullName);
106 bool generatedAux = tmpBool;
108 Log ("Released lock {0}", lockFile.FullName);