You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by di...@apache.org on 2010/05/10 17:43:41 UTC

svn commit: r942795 - /lucene/lucene.net/trunk/C#/src/Lucene.Net/Util/CloseableThreadLocal.cs

Author: digy
Date: Mon May 10 15:43:41 2010
New Revision: 942795

URL: http://svn.apache.org/viewvc?rev=942795&view=rev
Log:
LUCENENET-358 CloseableThreadLocal memory leak in LocalDataStoreSlot (with workaround)

Modified:
    lucene/lucene.net/trunk/C#/src/Lucene.Net/Util/CloseableThreadLocal.cs

Modified: lucene/lucene.net/trunk/C#/src/Lucene.Net/Util/CloseableThreadLocal.cs
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/src/Lucene.Net/Util/CloseableThreadLocal.cs?rev=942795&r1=942794&r2=942795&view=diff
==============================================================================
--- lucene/lucene.net/trunk/C#/src/Lucene.Net/Util/CloseableThreadLocal.cs (original)
+++ lucene/lucene.net/trunk/C#/src/Lucene.Net/Util/CloseableThreadLocal.cs Mon May 10 15:43:41 2010
@@ -44,69 +44,51 @@ namespace Lucene.Net.Util
 	public class CloseableThreadLocal
 	{
 		
-		private System.LocalDataStoreSlot t = System.Threading.Thread.AllocateDataSlot();
-		
-		private System.Collections.IDictionary hardRefs = new System.Collections.Hashtable();
+		[ThreadStatic]
+		static System.Collections.Generic.Dictionary<object, object> slots;
 		
 		public /*protected internal*/ virtual System.Object InitialValue()
 		{
 			return null;
 		}
-		
-		public virtual System.Object Get()
-		{
-			System.WeakReference weakRef = (System.WeakReference) System.Threading.Thread.GetData(t);
-			if (weakRef == null || weakRef.Target==null)
-			{
-				System.Object iv = InitialValue();
-				if (iv != null)
-				{
-					Set(iv);
-					return iv;
-				}
-				else
-					return null;
-			}
-			else
-			{
-				return weakRef.Target;
-			}
-		}
+
+        public virtual System.Object Get()
+        {
+            object value;
+
+            if (slots == null)
+            {
+                value = InitialValue();
+                if (value != null)
+                    Set(value);
+
+                return value;
+            }
+
+            if (slots.TryGetValue(this, out value))
+            {
+                return value;
+            }
+            else
+            {
+                value = InitialValue();
+                slots[this] = value;
+                return value;
+            }
+        }
 		
 		public virtual void  Set(System.Object object_Renamed)
 		{
-			
-			System.Threading.Thread.SetData(this.t, new System.WeakReference(object_Renamed));
-			
-			lock (hardRefs.SyncRoot)
-			{
-				hardRefs[SupportClass.ThreadClass.Current()] = object_Renamed;
-				
-				// Purge dead threads
-                System.Collections.ArrayList tmp = new System.Collections.ArrayList();
-                System.Collections.IEnumerator it = hardRefs.GetEnumerator();
-				while (it.MoveNext())
-				{
-					SupportClass.ThreadClass t = (SupportClass.ThreadClass) ((System.Collections.DictionaryEntry) it.Current).Key;
-					if (!t.IsAlive)
-					{
-                        tmp.Add(t);
-					}
-				}
-                foreach (SupportClass.ThreadClass th in tmp)
-                {
-                    hardRefs.Remove(th);
-                }
-            }
+			if (slots == null)
+				slots = new System.Collections.Generic.Dictionary<object, object>();
+
+			slots[this] = object_Renamed;	
 		}
 		
 		public virtual void  Close()
 		{
-			// Clear the hard refs; then, the only remaining refs to
-			// all values we were storing are weak (unless somewhere
-			// else is still using them) and so GC may reclaim them:
-			hardRefs = null;
-			t = null;
+            if(slots != null)
+                slots.Remove(this);
 		}
 	}
 }
\ No newline at end of file