main
 1using System;
 2using System.Collections;
 3using System.Collections.Generic;
 4using System.Threading;
 5
 6namespace jive
 7{
 8  public class PerThread : Context
 9  {
10    readonly IDictionary<int, LocalDataStoreSlot> slots;
11    readonly object mutex = new object();
12
13    public PerThread()
14    {
15      slots = new Dictionary<int, LocalDataStoreSlot>();
16    }
17
18    public bool contains<T>(Key<T> key)
19    {
20      return key.is_found_in(get_items());
21    }
22
23    public void add<T>(Key<T> key, T value)
24    {
25      key.add_value_to(get_items(), value);
26    }
27
28    public T value_for<T>(Key<T> key)
29    {
30      return key.parse_from(get_items());
31    }
32
33    public void remove<T>(Key<T> key)
34    {
35      key.remove_from(get_items());
36    }
37
38    IDictionary get_items()
39    {
40      var id = Thread.CurrentThread.ManagedThreadId;
41      within_lock(() =>
42          {
43          if (!slots.ContainsKey(id))
44          {
45          var slot = Thread.GetNamedDataSlot(GetType().FullName);
46          slots.Add(id, slot);
47          Thread.SetData(slot, new Hashtable());
48          }
49          });
50      return (IDictionary) Thread.GetData(slots[id]);
51    }
52
53    void within_lock(Action action)
54    {
55      lock (mutex) action();
56    }
57  }
58}