lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nightowl...@apache.org
Subject [lucenenet] 17/29: fix locking/disposal bug
Date Tue, 09 Jul 2019 21:29:33 GMT
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 <spiffcow@gmail.com>
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)


Mime
View raw message