Update the thread-local storage patch, to fix #335178
[beagle.git] / beagled / Lucene.Net / upstream-changes / 20_use-native-open-locking.patch
blob9feffe8899196762425fa1ebe9111beac143a10f
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
12 @@ -14,6 +14,7 @@
13 * limitations under the License.
15 using System;
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)
26 return true;
28 @@ -62,36 +64,45 @@ namespace Lucene.Net.Store
29 tmpBool = System.IO.Directory.Exists(Enclosing_Instance.lockDir.FullName);
30 if (!tmpBool)
32 - try
33 - {
34 - System.IO.Directory.CreateDirectory(Enclosing_Instance.lockDir.FullName);
35 - }
36 - catch (Exception)
37 + try
38 + {
39 + System.IO.Directory.CreateDirectory(Enclosing_Instance.lockDir.FullName);
40 + }
41 + catch (Exception)
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)) {
50 - try
51 - {
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);
55 - writer.Close ();
56 - createdFile.Close();
57 - obtainedLock = true;
58 - }
59 - catch (Exception e)
60 - {
61 - // Fall through
62 - }
63 - }
64 + try
65 + {
66 + int fd = Mono.Unix.Native.Syscall.open (
67 + lockFile.FullName,
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);
72 + if (fd == -1)
73 + throw new System.IO.IOException ("Could not create lock file: "
74 + + Mono.Unix.Native.Stdlib.strerror (
75 + Mono.Unix.Native.Stdlib.GetLastError ()
76 + ));
77 + int ret = Mono.Unix.Native.Syscall.close (fd);
78 + if (ret == -1)
79 + throw new System.IO.IOException ("Could not close lock file: "
80 + + Mono.Unix.Native.Stdlib.strerror (
81 + Mono.Unix.Native.Stdlib.GetLastError ()
82 + ));
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);
88 + return true;
89 + }
90 + catch (Exception e)
91 + {
92 + Log ("Exception in CreateNew for file:" + lockFile.FullName + ":" + e);
93 + return false;
94 + }
96 public override void Release()
98 @@ -110,6 +121,10 @@ namespace Lucene.Net.Store
100 else
101 tmpBool = false;
102 + if (System.IO.File.Exists(lockFile.FullName)) {
103 + Log ("Release didnt delete lockfile {0}.", lockFile.FullName);
104 + tmpBool = false;
106 bool generatedAux = tmpBool;
107 if (tmpBool)
108 Log ("Released lock {0}", lockFile.FullName);