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 2009/08/10 18:50:09 UTC
svn commit: r802856 -
/incubator/lucene.net/trunk/C#/src/Lucene.Net/Util/CloseableThreadLocal.cs
Author: digy
Date: Mon Aug 10 16:50:09 2009
New Revision: 802856
URL: http://svn.apache.org/viewvc?rev=802856&view=rev
Log:
New Impelemtation of CloseableThreadLocal (LUCENENET-186)
Modified:
incubator/lucene.net/trunk/C#/src/Lucene.Net/Util/CloseableThreadLocal.cs
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Util/CloseableThreadLocal.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Util/CloseableThreadLocal.cs?rev=802856&r1=802855&r2=802856&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Util/CloseableThreadLocal.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Util/CloseableThreadLocal.cs Mon Aug 10 16:50:09 2009
@@ -15,7 +15,9 @@
* limitations under the License.
*/
+using System;
using System.Threading;
+using System.Collections;
namespace Lucene.Net.Util
{
@@ -46,15 +48,48 @@
// i'm not sure if C#'s Thread.SetData(System.LocalDataStoreSlot, object) has the same issue.
// For now, i'll just implement this using Thread.SetData(System.LocalDataStoreSlot, object)
// and Thread.GetData(System.LocalDataStoreSlot) so that we're API compliant.
-
+
+
+
+ //public class CloseableThreadLocal
+ //{
+ // private System.LocalDataStoreSlot dataSlot;
+
+ // public CloseableThreadLocal()
+ // {
+ // dataSlot = Thread.AllocateDataSlot();
+ // }
+
+ // virtual protected object InitialValue()
+ // {
+ // return null;
+ // }
+
+ // public object Get()
+ // {
+ // object v = Thread.GetData(dataSlot);
+ // if (v == null)
+ // {
+ // v = InitialValue();
+ // Set(v);
+ // }
+ // return v;
+ // }
+
+ // public void Set(object v)
+ // {
+ // Thread.SetData(dataSlot, v);
+ // }
+
+ // public void Close()
+ // {
+ // }
+ //}
+
public class CloseableThreadLocal
{
- private System.LocalDataStoreSlot dataSlot;
-
- public CloseableThreadLocal()
- {
- dataSlot = Thread.AllocateDataSlot();
- }
+ private System.LocalDataStoreSlot t = Thread.AllocateDataSlot();
+ private Hashtable hardRefs = new Hashtable();
virtual protected object InitialValue()
{
@@ -63,22 +98,57 @@
public object Get()
{
- object v = Thread.GetData(dataSlot);
- if (v == null)
+ WeakReference weakRef = (WeakReference)Thread.GetData(t);
+ if (weakRef == null || weakRef.Target==null)
{
- v = InitialValue();
- Set(v);
+ Object iv = InitialValue();
+ if (iv != null)
+ {
+ Set(iv);
+ return iv;
+ }
+ else
+ return null;
+ }
+ else
+ {
+ Object v = weakRef.Target;
+ // This can never be null, because we hold a hard
+ // reference to the underlying object:
+ //assert v != null;
+ return v;
}
- return v;
}
-
- public void Set(object v)
+
+ public void Set(object obj)
{
- Thread.SetData(dataSlot, v);
+ Thread.SetData(t, new WeakReference(obj));
+
+ lock (hardRefs)
+ {
+ ArrayList tmp = new ArrayList();
+ hardRefs[Thread.CurrentThread] = obj;
+
+ foreach (Thread th in hardRefs.Keys)
+ {
+ //collect items to remove but don't remove them in the middle of enumeration.
+ if (!th.IsAlive) tmp.Add(th);
+ }
+ foreach (Thread th in tmp)
+ {
+ hardRefs.Remove(th);
+ }
+ }
}
+
public 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;
}
}
}