The Labs \ Source Viewer \ SSCLI \ System.Runtime.Remoting.Services \ ITrackingHandler

  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. ** File:    TrackingServices.cs
  18. **
  19. **
  20. ** Purpose: Defines the services for tracking lifetime and other
  21. **          operations on objects.
  22. **
  23. **
  24. ===========================================================*/
  25. namespace System.Runtime.Remoting.Services
  26. {
  27.     using System.Security.Permissions;
  28.     using System;
  29.     using System.Threading;
  30.     using System.Globalization;
  31.    
  32.     [System.Runtime.InteropServices.ComVisible(true)]
  33.     public interface ITrackingHandler
  34.     {
  35.         // Notify a handler that an object has been marshaled
  36.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  37.         void MarshaledObject(object obj, ObjRef or);
  38.        
  39.         // Notify a handler that an object has been unmarshaled
  40.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  41.         void UnmarshaledObject(object obj, ObjRef or);
  42.        
  43.         // Notify a handler that an object has been disconnected
  44.         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  45.         void DisconnectedObject(object obj);
  46.        
  47.     }
  48.    
  49.    
  50.     [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  51.     [System.Runtime.InteropServices.ComVisible(true)]
  52.     public class TrackingServices
  53.     {
  54.         // Private member variables
  55.         private static ITrackingHandler[] _Handlers = new ITrackingHandler[0];
  56.         // Array of registered tracking handlers
  57.         private static int _Size = 0;
  58.         // Number of elements in the array
  59.         private static object s_TrackingServicesSyncObject = null;
  60.        
  61.         private static object TrackingServicesSyncObject {
  62.             get {
  63.                 if (s_TrackingServicesSyncObject == null) {
  64.                     object o = new object();
  65.                     Interlocked.CompareExchange(ref s_TrackingServicesSyncObject, o, null);
  66.                 }
  67.                 return s_TrackingServicesSyncObject;
  68.             }
  69.         }
  70.        
  71.         public static void RegisterTrackingHandler(ITrackingHandler handler)
  72.         {
  73.             lock (TrackingServicesSyncObject) {
  74.                 // Validate arguments
  75.                 if (null == handler) {
  76.                     throw new ArgumentNullException("handler");
  77.                 }
  78.                
  79.                 // Check to make sure that the handler has not been registered
  80.                 if (-1 == Match(handler)) {
  81.                     // Allocate a new array if necessary
  82.                     if ((null == _Handlers) || (_Size == _Handlers.Length)) {
  83.                         ITrackingHandler[] temp = new ITrackingHandler[_Size * 2 + 4];
  84.                         if (null != _Handlers) {
  85.                             Array.Copy(_Handlers, temp, _Size);
  86.                         }
  87.                         _Handlers = temp;
  88.                     }
  89.                    
  90.                     _Handlers[_Size++] = handler;
  91.                 }
  92.                 else {
  93.                     throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_TrackingHandlerAlreadyRegistered"), "handler"));
  94.                 }
  95.             }
  96.         }
  97.        
  98.         public static void UnregisterTrackingHandler(ITrackingHandler handler)
  99.         {
  100.             lock (TrackingServicesSyncObject) {
  101.                 // Validate arguments
  102.                 if (null == handler) {
  103.                     throw new ArgumentNullException("handler");
  104.                 }
  105.                
  106.                 // Check to make sure that the channel has been registered
  107.                 int matchingIdx = Match(handler);
  108.                 if (-1 == matchingIdx) {
  109.                     throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_HandlerNotRegistered"), handler));
  110.                 }
  111.                
  112.                 // Delete the entry by copying the remaining entries
  113.                 Array.Copy(_Handlers, matchingIdx + 1, _Handlers, matchingIdx, _Size - matchingIdx - 1);
  114.                 _Size--;
  115.             }
  116.         }
  117.        
  118.         public static ITrackingHandler[] RegisteredHandlers {
  119.             get {
  120.                 lock (TrackingServicesSyncObject) {
  121.                     if (0 == _Size) {
  122.                         return new ITrackingHandler[0];
  123.                     }
  124.                     else {
  125.                         // Copy the array of registered handlers into a new array
  126.                         // and return
  127.                         ITrackingHandler[] temp = new ITrackingHandler[_Size];
  128.                         for (int i = 0; i < _Size; i++) {
  129.                             temp[i] = _Handlers[i];
  130.                         }
  131.                         return temp;
  132.                     }
  133.                 }
  134.             }
  135.         }
  136.        
  137.         // Notify all the handlers that an object has been marshaled
  138.         static internal void MarshaledObject(object obj, ObjRef or)
  139.         {
  140.             try {
  141.                 ITrackingHandler[] temp = _Handlers;
  142.                 for (int i = 0; i < _Size; i++) {
  143.                     temp[i].MarshaledObject(obj, or);
  144.                 }
  145.             }
  146.             catch {
  147.             }
  148.         }
  149.        
  150.         // Notify all the handlers that an object has been unmarshaled
  151.         static internal void UnmarshaledObject(object obj, ObjRef or)
  152.         {
  153.             try {
  154.                 ITrackingHandler[] temp = _Handlers;
  155.                 for (int i = 0; i < _Size; i++) {
  156.                     temp[i].UnmarshaledObject(obj, or);
  157.                 }
  158.             }
  159.             catch {
  160.             }
  161.         }
  162.        
  163.         // Notify all the handlers that an object has been disconnected
  164.         static internal void DisconnectedObject(object obj)
  165.         {
  166.             try {
  167.                 ITrackingHandler[] temp = _Handlers;
  168.                 for (int i = 0; i < _Size; i++) {
  169.                     temp[i].DisconnectedObject(obj);
  170.                 }
  171.             }
  172.             catch {
  173.             }
  174.         }
  175.        
  176.         private static int Match(ITrackingHandler handler)
  177.         {
  178.             int idx = -1;
  179.            
  180.             for (int i = 0; i < _Size; i++) {
  181.                 if (_Handlers[i] == handler) {
  182.                     idx = i;
  183.                     break;
  184.                 }
  185.             }
  186.            
  187.             return idx;
  188.         }
  189.     }
  190.    
  191. }
  192. // namespace

Developer Fusion