d455031e761f11b233eb55b65ffbbc57c7164458
[mono.git] / mcs / class / referencesource / mscorlib / system / sharedstatics.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 /*=============================================================================
7 **
8 ** Class: SharedStatics
9 **
10 **
11 ** Purpose: Container for statics that are shared across AppDomains.
12 **
13 **
14 =============================================================================*/
15
16 namespace System {
17
18     using System.Threading;
19     using System.Runtime.Remoting;
20     using System.Security;
21     using System.Security.Util;
22     using System.Runtime.CompilerServices;
23     using System.Runtime.ConstrainedExecution;
24     using System.Diagnostics.Contracts;
25 #if FEATURE_CAS_POLICY || FEATURE_LEGACYNETCFCRYPTO || MONO
26     using StringMaker = System.Security.Util.Tokenizer.StringMaker;
27 #endif // FEATURE_CAS_POLICY
28
29     internal sealed class SharedStatics
30     {
31 #if MONO
32         // TODO: We are using only GetSharedStringMaker for now which is
33         // ok to be AppDomain static
34         static readonly SharedStatics _sharedStatics = new SharedStatics();
35
36         private SharedStatics()
37         {
38         }
39 #else
40         // this is declared static but is actually forced to be the same object 
41         // for each AppDomain at AppDomain create time.
42         private static SharedStatics _sharedStatics;
43         
44         // Note: Do not add any code in this ctor because it is not called 
45         // when we set up _sharedStatics via AppDomain::SetupSharedStatics
46         private SharedStatics()
47         {
48             BCLDebug.Assert(false, "SharedStatics..ctor() is never called.");
49         }
50 #endif
51
52         private volatile String _Remoting_Identity_IDGuid;
53         public static String Remoting_Identity_IDGuid 
54         { 
55             [System.Security.SecuritySafeCritical]  // auto-generated
56             get 
57             {
58                 if (_sharedStatics._Remoting_Identity_IDGuid == null)
59                 {
60                     bool tookLock = false;
61                     RuntimeHelpers.PrepareConstrainedRegions();
62                     try {
63                         Monitor.Enter(_sharedStatics, ref tookLock);
64
65                         if (_sharedStatics._Remoting_Identity_IDGuid == null)
66                         {
67                             _sharedStatics._Remoting_Identity_IDGuid = Guid.NewGuid().ToString().Replace('-', '_');
68                         }
69                     }
70                     finally {
71                         if (tookLock)
72                             Monitor.Exit(_sharedStatics);
73                     }
74                 }
75
76                 Contract.Assert(_sharedStatics._Remoting_Identity_IDGuid != null,
77                                 "_sharedStatics._Remoting_Identity_IDGuid != null");
78                 return _sharedStatics._Remoting_Identity_IDGuid;
79             } 
80         }
81
82 #if FEATURE_CAS_POLICY || FEATURE_LEGACYNETCFCRYPTO || MONO
83         private StringMaker _maker;
84         [System.Security.SecuritySafeCritical]  // auto-generated
85         static public StringMaker GetSharedStringMaker()
86         {
87             StringMaker maker = null;
88             
89             bool tookLock = false;
90             RuntimeHelpers.PrepareConstrainedRegions();
91             try {
92                 Monitor.Enter(_sharedStatics, ref tookLock);
93
94                 if (_sharedStatics._maker != null)
95                 {
96                     maker = _sharedStatics._maker;
97                     _sharedStatics._maker = null;
98                 }
99             }
100             finally {
101                 if (tookLock)
102                     Monitor.Exit(_sharedStatics);
103             }
104             
105             if (maker == null)
106             {
107                 maker = new StringMaker();
108             }
109             
110             return maker;
111         }
112
113         [System.Security.SecuritySafeCritical]  // auto-generated
114         static public void ReleaseSharedStringMaker(ref StringMaker maker)
115         {
116             // save this stringmaker so someone else can use it
117             bool tookLock = false;
118             RuntimeHelpers.PrepareConstrainedRegions();
119             try
120             {
121                 Monitor.Enter(_sharedStatics, ref tookLock);
122
123                 _sharedStatics._maker = maker;
124                 maker = null;
125             }
126             finally {
127                 if (tookLock)
128                     Monitor.Exit(_sharedStatics);
129             }
130         }
131 #endif // FEATURE_CAS_POLICY
132
133         // Note this may not need to be process-wide.
134         private int _Remoting_Identity_IDSeqNum;
135         internal static int Remoting_Identity_GetNextSeqNum()
136         {
137             return Interlocked.Increment(ref _sharedStatics._Remoting_Identity_IDSeqNum);
138         }
139
140
141         // This is the total amount of memory currently "reserved" via
142         // all MemoryFailPoints allocated within the process.
143         // Stored as a long because we need to use Interlocked.Add.
144         private long _memFailPointReservedMemory;
145
146         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
147         internal static long AddMemoryFailPointReservation(long size)
148         {
149             // Size can legitimately be negative - see Dispose.
150             return Interlocked.Add(ref _sharedStatics._memFailPointReservedMemory, (long) size);
151         }
152
153         internal static ulong MemoryFailPointReservedMemory {
154             get { 
155                 Contract.Assert(Volatile.Read(ref _sharedStatics._memFailPointReservedMemory) >= 0, "Process-wide MemoryFailPoint reserved memory was negative!");
156                 return (ulong) Volatile.Read(ref _sharedStatics._memFailPointReservedMemory);
157             }
158         }
159     }
160 }