From: Debajyoti Bera <dbera.web@gmail.com>

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).

diff -u Store/FSDirectory.cs Store/FSDirectory.cs
--- Store/FSDirectory.cs	23 Mar 2006 13:50:28 -0000
+++ Store/FSDirectory.cs	31 May 2006 18:37:11 -0000
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 using System;
+using Mono.Unix.Native;
 using Constants = Lucene.Net.Util.Constants;
 namespace Lucene.Net.Store
 {
@@ -52,6 +53,7 @@
 			}
 			public override bool Obtain()
 			{
+				Log ("Trying to obtain lock " + lockFile.FullName);
 				if (Lucene.Net.Store.FSDirectory.DISABLE_LOCKS || Enclosing_Instance.DisableLocks)
 					return true;
 				
@@ -62,36 +64,42 @@
 					tmpBool = System.IO.Directory.Exists(Enclosing_Instance.lockDir.FullName);
 				if (!tmpBool)
 				{
-                    try
-                    {
-                        System.IO.Directory.CreateDirectory(Enclosing_Instance.lockDir.FullName);
-                    }
-                    catch (Exception)
+					try
+                    			{
+						System.IO.Directory.CreateDirectory(Enclosing_Instance.lockDir.FullName);
+                    			}
+                    			catch (Exception)
 					{
 						throw new System.IO.IOException("Cannot create lock directory: " + Enclosing_Instance.lockDir);
 					}
 				}
 
-				bool obtainedLock = false;
+                try
+                {
+		    int fd = Mono.Unix.Native.Syscall.open (
+				lockFile.FullName,
+				Mono.Unix.Native.OpenFlags.O_RDWR | 
+				Mono.Unix.Native.OpenFlags.O_CREAT |
+				Mono.Unix.Native.OpenFlags.O_EXCL,
+				Mono.Unix.Native.FilePermissions.S_IRUSR);
+		    if (fd == -1)
+			    throw new System.IO.IOException ("Could not create lock file: "
+				    + Mono.Unix.Native.Stdlib.strerror (
+					    Mono.Unix.Native.Stdlib.GetLastError ()
+				    ));
 
-				if (! System.IO.File.Exists(lockFile.FullName)) {
-                	try
-	                {
-    	                System.IO.FileStream createdFile = lockFile.Create();
-						System.IO.StreamWriter writer = new System.IO.StreamWriter (createdFile);
-						writer.WriteLine (System.Diagnostics.Process.GetCurrentProcess().Id);
-						writer.Close ();
-                    	createdFile.Close();
-	                    obtainedLock = true;
-    	            }
-        	        catch (Exception e)
-            	    {
-                	    // Fall through
-	                }
-				}
+		    System.IO.StreamWriter w = new System.IO.StreamWriter (new Mono.Unix.UnixStream (fd, false));
+		    w.WriteLine (System.Diagnostics.Process.GetCurrentProcess ().Id);
+		    w.Close ();
 
-				Log ("{0} lock {1}", obtainedLock ? "Obtained" : "Could not obtain", lockFile.FullName);
-				return obtainedLock;
+		    Log ("Obtained lock " + lockFile.FullName);
+                    return true;
+                }
+                catch (Exception e)
+                {
+		    Log ("Exception in CreateNew for file:" + lockFile.FullName + ":" + e);
+                    return false;
+                }
 			}
 			public override void  Release()
 			{
@@ -110,6 +118,10 @@
 				}
 				else
 					tmpBool = false;
+				if (System.IO.File.Exists(lockFile.FullName)) {
+					Log ("Release didnt delete lockfile {0}.", lockFile.FullName);
+					tmpBool = false;
+				}
 				bool generatedAux = tmpBool;
 				if (tmpBool)
 					Log ("Released lock {0}", lockFile.FullName);
