Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
MicroThreadLocal.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections.Generic;
5 
6 namespace SiliconStudio.Core.MicroThreading
7 {
8  /// <summary>
9  /// Provides microthread-local storage of data.
10  /// </summary>
11  /// <typeparam name="T"></typeparam>
12  public class MicroThreadLocal<T>
13  {
14  private readonly Func<T> valueFactory;
15  private readonly Dictionary<MicroThread, T> values = new Dictionary<MicroThread, T>();
16 
17  /// <summary>
18  /// The value return when we are not in a micro thread. That is the value return when 'Scheduler.CurrentMicroThread==null'
19  /// </summary>
20  private T valueOutOfMicrothread;
21 
22  /// <summary>
23  /// Indicate if the value out of micro-thread have been set at least once or not.
24  /// </summary>
25  private bool valueOutOfMicrothreadSet;
26 
27  /// <summary>
28  /// Initializes a new instance of the <see cref="MicroThreadLocal{T}"/> class.
29  /// </summary>
31  : this(null)
32  {
33  }
34 
35  /// <summary>
36  /// Initializes a new instance of the <see cref="MicroThreadLocal{T}"/> class.
37  /// </summary>
38  /// <param name="valueFactory">The value factory invoked to create a value when <see cref="Value"/> is retrieved before having been previously initialized.</param>
39  public MicroThreadLocal(Func<T> valueFactory)
40  {
41  this.valueFactory = valueFactory;
42  }
43 
44  /// <summary>
45  /// Gets or sets the value for the current microthread.
46  /// </summary>
47  /// <value>
48  /// The value for the current microthread.
49  /// </value>
50  public T Value
51  {
52  get
53  {
54  T value;
55  var microThread = Scheduler.CurrentMicroThread;
56 
57  lock (values)
58  {
59  if (microThread == null)
60  {
61  if (!valueOutOfMicrothreadSet)
62  valueOutOfMicrothread = valueFactory != null ? valueFactory() : default(T);
63  value = valueOutOfMicrothread;
64  }
65  else if (!values.TryGetValue(microThread, out value))
66  values.Add(microThread, value = valueFactory != null ? valueFactory() : default(T));
67  }
68 
69  return value;
70  }
71  set
72  {
73  var microThread = Scheduler.CurrentMicroThread;
74 
75  lock (values)
76  {
77  if (microThread == null)
78  {
79  valueOutOfMicrothread = value;
80  valueOutOfMicrothreadSet = true;
81  }
82  else
83  {
84  values[microThread] = value;
85  }
86  }
87  }
88  }
89 
90  public void ClearValue()
91  {
92  var microThread = Scheduler.CurrentMicroThread;
93 
94  lock (values)
95  {
96  if (microThread == null)
97  {
98  valueOutOfMicrothread = default(T);
99  valueOutOfMicrothreadSet = false;
100  }
101  else
102  {
103  values.Remove(microThread);
104  }
105  }
106  }
107  }
108 }
MicroThreadLocal()
Initializes a new instance of the MicroThreadLocal{T} class.
MicroThreadLocal(Func< T > valueFactory)
Initializes a new instance of the MicroThreadLocal{T} class.