Return-Path: Delivered-To: apmail-lucene-lucene-net-commits-archive@www.apache.org Received: (qmail 9623 invoked from network); 10 May 2010 15:44:39 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 10 May 2010 15:44:39 -0000 Received: (qmail 28176 invoked by uid 500); 10 May 2010 15:44:39 -0000 Delivered-To: apmail-lucene-lucene-net-commits-archive@lucene.apache.org Received: (qmail 28129 invoked by uid 500); 10 May 2010 15:44:39 -0000 Mailing-List: contact lucene-net-commits-help@lucene.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: lucene-net-dev@lucene.apache.org Delivered-To: mailing list lucene-net-commits@lucene.apache.org Received: (qmail 27842 invoked by uid 99); 10 May 2010 15:44:39 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 10 May 2010 15:44:39 +0000 X-ASF-Spam-Status: No, hits=-1157.7 required=10.0 tests=ALL_TRUSTED,AWL X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 10 May 2010 15:44:37 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 7BFB923888E3; Mon, 10 May 2010 15:43:41 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r942795 - /lucene/lucene.net/trunk/C#/src/Lucene.Net/Util/CloseableThreadLocal.cs Date: Mon, 10 May 2010 15:43:41 -0000 To: lucene-net-commits@lucene.apache.org From: digy@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100510154341.7BFB923888E3@eris.apache.org> 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 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(); + + 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