The Labs \ Source Viewer \ SSCLI \ System \ SharedStatics

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. /*=============================================================================
  16. **
  17. ** Class: SharedStatics
  18. **
  19. **
  20. ** Purpose: Container for statics that are shared across AppDomains.
  21. **
  22. **
  23. =============================================================================*/
  24. namespace System
  25. {
  26.    
  27.     using System.Threading;
  28.     using System.Runtime.Remoting;
  29.     using System.Security;
  30.     using System.Security.Util;
  31.     using System.Runtime.CompilerServices;
  32.     using System.Runtime.ConstrainedExecution;
  33.     using StringMaker = System.Security.Util.Tokenizer.StringMaker;
  34.    
  35.     internal sealed class SharedStatics
  36.     {
  37.         // this is declared static but is actually forced to be the same object
  38.         // for each AppDomain at AppDomain create time.
  39.         static internal SharedStatics _sharedStatics;
  40.        
  41.         // when we create the single object we can construct anything we will need
  42.         // here. If not too many, then just create them all in the constructor, otherwise
  43.         // can have the property check & create. Need to be aware of threading issues
  44.         // when do so though.
  45.         // Note: This ctor is not called when we setup _sharedStatics via AppDomain::SetupSharedStatics
  46.         SharedStatics()
  47.         {
  48.             _Remoting_Identity_IDGuid = null;
  49.             _Remoting_Identity_IDSeqNum = 64;
  50.             // Reserve initial numbers for well known objects.
  51.             _maker = null;
  52.         }
  53.        
  54.         private string _Remoting_Identity_IDGuid;
  55.         public static string Remoting_Identity_IDGuid {
  56.             get {
  57.                 if (_sharedStatics._Remoting_Identity_IDGuid == null) {
  58.                     bool tookLock = false;
  59.                     RuntimeHelpers.PrepareConstrainedRegions();
  60.                     try {
  61.                         Monitor.ReliableEnter(_sharedStatics, ref tookLock);
  62.                        
  63.                         if (_sharedStatics._Remoting_Identity_IDGuid == null) {
  64.                             _sharedStatics._Remoting_Identity_IDGuid = Guid.NewGuid().ToString().Replace('-', '_');
  65.                         }
  66.                     }
  67.                     finally {
  68.                         if (tookLock)
  69.                             Monitor.Exit(_sharedStatics);
  70.                     }
  71.                 }
  72.                
  73.                 BCLDebug.Assert(_sharedStatics._Remoting_Identity_IDGuid != null, "_sharedStatics._Remoting_Identity_IDGuid != null");
  74.                 return _sharedStatics._Remoting_Identity_IDGuid;
  75.             }
  76.         }
  77.        
  78.         private StringMaker _maker;
  79.         public static StringMaker GetSharedStringMaker()
  80.         {
  81.             StringMaker maker = null;
  82.            
  83.             bool tookLock = false;
  84.             RuntimeHelpers.PrepareConstrainedRegions();
  85.             try {
  86.                 Monitor.ReliableEnter(_sharedStatics, ref tookLock);
  87.                
  88.                 if (_sharedStatics._maker != null) {
  89.                     maker = _sharedStatics._maker;
  90.                     _sharedStatics._maker = null;
  91.                 }
  92.             }
  93.             finally {
  94.                 if (tookLock)
  95.                     Monitor.Exit(_sharedStatics);
  96.             }
  97.            
  98.             if (maker == null) {
  99.                 maker = new StringMaker();
  100.             }
  101.            
  102.             return maker;
  103.         }
  104.        
  105.         public static void ReleaseSharedStringMaker(ref StringMaker maker)
  106.         {
  107.             // save this stringmaker so someone else can use it
  108.             bool tookLock = false;
  109.             RuntimeHelpers.PrepareConstrainedRegions();
  110.             try {
  111.                 Monitor.ReliableEnter(_sharedStatics, ref tookLock);
  112.                
  113.                 _sharedStatics._maker = maker;
  114.                 maker = null;
  115.             }
  116.             finally {
  117.                 if (tookLock)
  118.                     Monitor.Exit(_sharedStatics);
  119.             }
  120.         }
  121.        
  122.         // Note this may not need to be process-wide.
  123.         private int _Remoting_Identity_IDSeqNum;
  124.         static internal int Remoting_Identity_GetNextSeqNum()
  125.         {
  126.             return Interlocked.Increment(ref _sharedStatics._Remoting_Identity_IDSeqNum);
  127.         }
  128.        
  129.        
  130.         // This is the total amount of memory currently "reserved" via
  131.         // all MemoryFailPoints allocated within the process.
  132.         // Stored as a long because we need to use Interlocked.Add.
  133.         private long _memFailPointReservedMemory;
  134.        
  135.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  136.         static internal long AddMemoryFailPointReservation(long size)
  137.         {
  138.             // Size can legitimately be negative - see Dispose.
  139.             return Interlocked.Add(ref _sharedStatics._memFailPointReservedMemory, (long)size);
  140.         }
  141.        
  142.         static internal ulong MemoryFailPointReservedMemory {
  143.             get {
  144.                 BCLDebug.Assert(_sharedStatics._memFailPointReservedMemory >= 0, "Process-wide MemoryFailPoint reserved memory was negative!");
  145.                 return (ulong)_sharedStatics._memFailPointReservedMemory;
  146.             }
  147.         }
  148.     }
  149. }

Developer Fusion