This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git

commit 7f6c78570d4b7e5e4bbb8708acfe3a397822baca
Author: sourcerist <[email protected]>
AuthorDate: Fri Feb 8 14:44:47 2019 -0800

    fix locking/disposal bug
---
 src/Lucene.Net/Store/NativeFSLockFactory.cs | 72 ++++++++++++++++-------------
 1 file changed, 39 insertions(+), 33 deletions(-)

diff --git a/src/Lucene.Net/Store/NativeFSLockFactory.cs 
b/src/Lucene.Net/Store/NativeFSLockFactory.cs
index b5b65fc..6b253b8 100644
--- a/src/Lucene.Net/Store/NativeFSLockFactory.cs
+++ b/src/Lucene.Net/Store/NativeFSLockFactory.cs
@@ -88,16 +88,17 @@ namespace Lucene.Net.Store
             SetLockDir(lockDir);
         }
 
-        // LUCENENET: NativeFSLocks in Java are infact singletons; this is how 
we mimick that to track instances and make sure
-        // IW.Unlock and IW.IsLocked works correctly
-        internal static readonly Dictionary<string, Lock> _locks = new 
Dictionary<string, Lock>();
-
-        /// <summary>
-        /// Given a lock name, return the full prefixed path of the actual 
lock file.
-        /// </summary>
-        /// <param name="lockName"></param>
-        /// <returns></returns>
-        private string GetCanonicalPathOfLockFile(string lockName)
+               // LUCENENET: NativeFSLocks in Java are infact singletons; this 
is how we mimick that to track instances and make sure
+               // IW.Unlock and IW.IsLocked works correctly
+        private static readonly Dictionary<string, Lock> _locks = new 
Dictionary<string, Lock>();
+               private static readonly object _locks_lockObj = new object();
+
+               /// <summary>
+               /// Given a lock name, return the full prefixed path of the 
actual lock file.
+               /// </summary>
+               /// <param name="lockName"></param>
+               /// <returns></returns>
+               private string GetCanonicalPathOfLockFile(string lockName)
         {
             if (m_lockPrefix != null)
             {
@@ -110,9 +111,11 @@ namespace Lucene.Net.Store
         {
             var path = GetCanonicalPathOfLockFile(lockName);
             Lock l;
-            lock (_locks)
-                if (!_locks.TryGetValue(path, out l))
-                    _locks.Add(path, l = NewLock(path));
+                       lock (_locks_lockObj)
+                       {
+                               if (!_locks.TryGetValue(path, out l))
+                                       _locks.Add(path, l = NewLock(path));
+                       }
             return l;
         }
 
@@ -130,14 +133,16 @@ namespace Lucene.Net.Store
         {
             var path = GetCanonicalPathOfLockFile(lockName);
             Lock l;
-            // this is the reason why we can't use ConcurrentDictionary: we 
need the removal and disposal of the lock to be atomic
-            // otherwise it may clash with MakeLock making a lock and 
ClearLock disposing of it in another thread.
-            lock (_locks)
-                if (_locks.TryGetValue(path, out l))
-                {
-                    _locks.Remove(path);
-                    l.Dispose();
-                }
+                       // this is the reason why we can't use 
ConcurrentDictionary: we need the removal and disposal of the lock to be atomic
+                       // otherwise it may clash with MakeLock making a lock 
and ClearLock disposing of it in another thread.
+                       lock (_locks_lockObj)
+                       {
+                               if (_locks.TryGetValue(path, out l))
+                               {
+                                       _locks.Remove(path);
+                                       l.Dispose();
+                               }
+                       }
         }
     }
 
@@ -164,6 +169,7 @@ namespace Lucene.Net.Store
         private FileStream channel;
         private readonly string path;
         private readonly DirectoryInfo lockDir;
+               private readonly object lockObject = new object(); // avoid 
lock(this)
 
         public NativeFSLock(NativeFSLockFactory outerInstance, DirectoryInfo 
lockDir, string path)
         {
@@ -174,7 +180,7 @@ namespace Lucene.Net.Store
 
         public override bool Obtain()
         {
-            lock (this)
+            lock (lockObject)
             {
                 FailureReason = null;
 
@@ -242,15 +248,15 @@ namespace Lucene.Net.Store
         {
             if (disposing)
             {
-                lock (this)
+                lock (lockObject)
                 {
                     // whether or not we have created a file, we need to remove
                     // the lock instance from the dictionary that tracks them.
                     try
                     {
-                        lock (NativeFSLockFactory._locks)
-                            NativeFSLockFactory._locks.Remove(path);
-                    }
+                                               outerInstance?.ClearLock(path);
+
+                                       }
                     finally
                     {
                         if (channel != null)
@@ -285,7 +291,7 @@ namespace Lucene.Net.Store
 
         public override bool IsLocked()
         {
-            lock (this)
+            lock (lockObject)
             {
                 // The test for is isLocked is not directly possible with 
native file locks:
 
@@ -336,8 +342,9 @@ namespace Lucene.Net.Store
         private FileStream channel;
         private readonly string path;
         private readonly DirectoryInfo lockDir;
+               private readonly object lockObject = new object(); // avoid 
lock(this)
 
-        public SharingAwareNativeFSLock(NativeFSLockFactory outerInstance, 
DirectoryInfo lockDir, string path)
+               public SharingAwareNativeFSLock(NativeFSLockFactory 
outerInstance, DirectoryInfo lockDir, string path)
         {
             this.outerInstance = outerInstance;
             this.lockDir = lockDir;
@@ -376,7 +383,7 @@ namespace Lucene.Net.Store
 
         public override bool Obtain()
         {
-            lock (this)
+            lock (lockObject)
             {
                 FailureReason = null;
 
@@ -461,14 +468,13 @@ namespace Lucene.Net.Store
         {
             if (disposing)
             {
-                lock (this)
+                lock (lockObject)
                 {
                     // whether or not we have created a file, we need to remove
                     // the lock instance from the dictionary that tracks them.
                     try
                     {
-                        lock (NativeFSLockFactory._locks)
-                            NativeFSLockFactory._locks.Remove(path);
+                                               outerInstance?.ClearLock(path);
                     }
                     finally
                     {
@@ -500,7 +506,7 @@ namespace Lucene.Net.Store
 
         public override bool IsLocked()
         {
-            lock (this)
+            lock (lockObject)
             {
                 // First a shortcut, if a lock reference in this instance is 
available
                 if (channel != null)

Reply via email to