summaryrefslogtreecommitdiff
path: root/lib/infrastructure/threading/PerThread.cs
blob: 6eed1370f2f8c9b9ceaed7824c3cdabb93a15e4b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using jive.utility;

namespace jive.infrastructure.threading
{
  public class PerThread : Context
  {
    readonly IDictionary<int, LocalDataStoreSlot> slots;
    readonly object mutex = new object();

    public PerThread()
    {
      slots = new Dictionary<int, LocalDataStoreSlot>();
    }

    public bool contains<T>(Key<T> key)
    {
      return key.is_found_in(get_items());
    }

    public void add<T>(Key<T> key, T value)
    {
      key.add_value_to(get_items(), value);
    }

    public T value_for<T>(Key<T> key)
    {
      return key.parse_from(get_items());
    }

    public void remove<T>(Key<T> key)
    {
      key.remove_from(get_items());
    }

    IDictionary get_items()
    {
      var id = Thread.CurrentThread.ManagedThreadId;
      within_lock(() =>
          {
          if (!slots.ContainsKey(id))
          {
          var slot = Thread.GetNamedDataSlot(GetType().FullName);
          slots.Add(id, slot);
          Thread.SetData(slot, new Hashtable());
          }
          });
      return (IDictionary) Thread.GetData(slots[id]);
    }

    void within_lock(Action action)
    {
      lock (mutex) action();
    }
  }
}