The Labs \ Source Viewer \ SSCLI \ System.Runtime.Remoting.Lifetime \ LeaseLifeTimeServiceProperty

  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. // Microsoft Windows
  18. // File: LifetimeServices.cs
  19. //
  20. // Contents: Used to obtain a lease
  21. //
  22. // History: 1/5/00 Created
  23. //
  24. //+----------------------------------------------------------------------------
  25. namespace System.Runtime.Remoting.Lifetime
  26. {
  27.    
  28.     using System;
  29.     using System.Threading;
  30.     using System.Security;
  31.     using System.Security.Permissions;
  32.     using System.Runtime.Remoting.Contexts;
  33.     using System.Runtime.Remoting.Messaging;
  34.     using System.Globalization;
  35.    
  36.     // access needs to be restricted
  37.     [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  38.     [System.Runtime.InteropServices.ComVisible(true)]
  39.     public sealed class LifetimeServices
  40.     {
  41.         // Set once boolean
  42.         private static bool isLeaseTime = false;
  43.         private static bool isRenewOnCallTime = false;
  44.         private static bool isSponsorshipTimeout = false;
  45.        
  46.         // Default values
  47.         private static TimeSpan m_leaseTime = TimeSpan.FromMinutes(5);
  48.         private static TimeSpan m_renewOnCallTime = TimeSpan.FromMinutes(2);
  49.         private static TimeSpan m_sponsorshipTimeout = TimeSpan.FromMinutes(2);
  50.         private static TimeSpan m_pollTime = TimeSpan.FromMilliseconds(10000);
  51.        
  52.         // Testing values
  53.         //private static TimeSpan m_leaseTime = TimeSpan.FromSeconds(20);
  54.         //private static TimeSpan m_renewOnCallTime = TimeSpan.FromSeconds(20);
  55.         //private static TimeSpan m_sponsorshipTimeout = TimeSpan.FromSeconds(20);
  56.         //private static TimeSpan m_pollTime = TimeSpan.FromMilliseconds(10000);
  57.        
  58.         private static object s_LifetimeSyncObject = null;
  59.        
  60.         private static object LifetimeSyncObject {
  61.             get {
  62.                 if (s_LifetimeSyncObject == null) {
  63.                     object o = new object();
  64.                     Interlocked.CompareExchange(ref s_LifetimeSyncObject, o, null);
  65.                 }
  66.                 return s_LifetimeSyncObject;
  67.             }
  68.         }
  69.        
  70.         // Initial Lease Time span for appdomain
  71.         public static TimeSpan LeaseTime {
  72.             get { return m_leaseTime; }
  73.            
  74.             [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.RemotingConfiguration)]
  75.             set {
  76.                 lock (LifetimeSyncObject) {
  77.                     if (isLeaseTime)
  78.                         throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Lifetime_SetOnce"), "LeaseTime"));
  79.                    
  80.                    
  81.                     m_leaseTime = value;
  82.                     isLeaseTime = true;
  83.                 }
  84.             }
  85.         }
  86.        
  87.        
  88.         // Initial renew on call time span for appdomain
  89.         public static TimeSpan RenewOnCallTime {
  90.            
  91.             get { return m_renewOnCallTime; }
  92.             [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.RemotingConfiguration)]
  93.             set {
  94.                 lock (LifetimeSyncObject) {
  95.                     if (isRenewOnCallTime)
  96.                         throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Lifetime_SetOnce"), "RenewOnCallTime"));
  97.                    
  98.                    
  99.                     m_renewOnCallTime = value;
  100.                     isRenewOnCallTime = true;
  101.                 }
  102.             }
  103.         }
  104.        
  105.        
  106.        
  107.         // Initial sponsorshiptimeout for appdomain
  108.         public static TimeSpan SponsorshipTimeout {
  109.            
  110.             get { return m_sponsorshipTimeout; }
  111.             [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.RemotingConfiguration)]
  112.             set {
  113.                 lock (LifetimeSyncObject) {
  114.                     if (isSponsorshipTimeout)
  115.                         throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Lifetime_SetOnce"), "SponsorshipTimeout"));
  116.                     m_sponsorshipTimeout = value;
  117.                     isSponsorshipTimeout = true;
  118.                 }
  119.             }
  120.         }
  121.        
  122.        
  123.        
  124.         // Initial sponsorshiptimeout for appdomain
  125.         public static TimeSpan LeaseManagerPollTime {
  126.            
  127.             get { return m_pollTime; }
  128.             [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.RemotingConfiguration)]
  129.             set {
  130.                 lock (LifetimeSyncObject) {
  131.                     m_pollTime = value;
  132.                     if (LeaseManager.IsInitialized())
  133.                         LeaseManager.GetLeaseManager().ChangePollTime(m_pollTime);
  134.                 }
  135.             }
  136.         }
  137.        
  138.        
  139.        
  140.        
  141.        
  142.         static internal ILease GetLeaseInitial(MarshalByRefObject obj)
  143.         {
  144.             ILease lease = null;
  145.             LeaseManager leaseManager = LeaseManager.GetLeaseManager(LeaseManagerPollTime);
  146.             lease = (ILease)leaseManager.GetLease(obj);
  147.             if (lease == null)
  148.                 lease = CreateLease(obj);
  149.             return lease;
  150.            
  151.         }
  152.        
  153.        
  154.        
  155.         static internal ILease GetLease(MarshalByRefObject obj)
  156.         {
  157.             ILease lease = null;
  158.             LeaseManager leaseManager = LeaseManager.GetLeaseManager(LeaseManagerPollTime);
  159.             lease = (ILease)leaseManager.GetLease(obj);
  160.             return lease;
  161.            
  162.         }
  163.        
  164.        
  165.        
  166.        
  167.         //internal static ILease CreateLease(MarshalByRefObject obj, IMessageSink nextSink)
  168.        
  169.        
  170.         static internal ILease CreateLease(MarshalByRefObject obj)
  171.         {
  172.             return CreateLease(LeaseTime, RenewOnCallTime, SponsorshipTimeout, obj);
  173.            
  174.         }
  175.        
  176.        
  177.        
  178.         static internal ILease CreateLease(TimeSpan leaseTime, TimeSpan renewOnCallTime, TimeSpan sponsorshipTimeout, MarshalByRefObject obj)
  179.         {
  180.             // Will create leaseManager if not already created.
  181.             LeaseManager.GetLeaseManager(LeaseManagerPollTime);
  182.             return (ILease)(new Lease(leaseTime, renewOnCallTime, sponsorshipTimeout, obj));
  183.            
  184.         }
  185.        
  186.     }
  187.    
  188.    
  189.     [Serializable()]
  190.     internal class LeaseLifeTimeServiceProperty : IContextProperty, IContributeObjectSink
  191.     {
  192.        
  193.        
  194.         public string Name {
  195.            
  196.             get { return "LeaseLifeTimeServiceProperty"; }
  197.         }
  198.        
  199.        
  200.        
  201.        
  202.         public bool IsNewContextOK(Context newCtx)
  203.         {
  204.             return true;
  205.            
  206.         }
  207.        
  208.        
  209.        
  210.         public void Freeze(Context newContext)
  211.         {
  212.            
  213.         }
  214.        
  215.        
  216.         // Initiates the creation of a lease
  217.        
  218.         // Creates a sink for invoking a renew on call when an object is created.
  219.        
  220.        
  221.         public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink)
  222.         {
  223.             bool fServer;
  224.             ServerIdentity identity = (ServerIdentity)MarshalByRefObject.GetIdentity(obj, out fServer);
  225.             BCLDebug.Assert(identity != null, "[LifetimeServices.GetObjectSink] identity != null");
  226.            
  227.             // NOTE: Single Call objects do not have a lease associated with it because they last
  228.             // only for the duration of the call.
  229.             // Singleton objects on the other hand do have leases associated with them and they can
  230.             // be garbage collected.
  231.             if (identity.IsSingleCall()) {
  232.                 BCLDebug.Trace("REMOTE", "LeaseLifeTimeServiceProperty.GetObjectSink, no lease SingleCall", obj, ", NextSink " + nextSink);
  233.                 return nextSink;
  234.             }
  235.            
  236.            
  237.            
  238.             // Create lease. InitializeLifetimeService is a virtual method which can be overridded so that a lease with
  239.             // object specific properties can be created.
  240.             object leaseObj = obj.InitializeLifetimeService();
  241.            
  242.            
  243.             BCLDebug.Trace("REMOTE", "LeaseLifeTimeServiceProperty.GetObjectSink, return from InitializeLifetimeService obj ", obj, ", lease ", leaseObj);
  244.            
  245.            
  246.             // InitializeLifetimeService can return a lease in one of conditions:
  247.             // 1) the lease has a null state which specifies that no lease is to be created.
  248.             // 2) the lease has an initial state which specifies that InitializeLifeTimeService has created a new lease.
  249.             // 3) the lease has another state which indicates that the lease has already been created and registered.
  250.            
  251.            
  252.             if (leaseObj == null) {
  253.                 BCLDebug.Trace("REMOTE", "LeaseLifeTimeServiceProperty.GetObjectSink, no lease ", obj, ", NextSink " + nextSink);
  254.                 return nextSink;
  255.             }
  256.            
  257.             if (!(leaseObj is System.Runtime.Remoting.Lifetime.ILease))
  258.                 throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Lifetime_ILeaseReturn"), leaseObj));
  259.            
  260.             ILease ilease = (ILease)leaseObj;
  261.            
  262.             if (ilease.InitialLeaseTime.CompareTo(TimeSpan.Zero) <= 0) {
  263.                 // No lease
  264.                 {
  265.                     BCLDebug.Trace("REMOTE", "LeaseLifeTimeServiceProperty.GetObjectSink, no lease because InitialLeaseTime is Zero ", obj);
  266.                     if (ilease is System.Runtime.Remoting.Lifetime.Lease) {
  267.                         ((Lease)ilease).Remove();
  268.                     }
  269.                     return nextSink;
  270.                 }
  271.             }
  272.            
  273.            
  274.             Lease lease = null;
  275.             lock (identity) {
  276.                 if (identity.Lease != null) {
  277.                     // Lease already exists for object, object is being marsalled again
  278.                     BCLDebug.Trace("REMOTE", "LeaseLifeTimeServiceProperty.GetObjectSink, Lease already exists for object ", obj);
  279.                     lease = (Lease)identity.Lease;
  280.                     lease.Renew(lease.InitialLeaseTime);
  281.                     // Reset initial lease time
  282.                 }
  283.                 else {
  284.                     // New lease
  285.                     if (!(ilease is System.Runtime.Remoting.Lifetime.Lease)) {
  286.                         // InitializeLifetimeService created its own ILease object
  287.                         // Need to create a System.Runtime.Remoting.Lease object
  288.                         BCLDebug.Trace("REMOTE", "LeaseLifeTimeServiceProperty.GetObjectSink, New Lease, lease not of type Lease ", obj);
  289.                         lease = (Lease)LifetimeServices.GetLeaseInitial(obj);
  290.                         if (lease.CurrentState == LeaseState.Initial) {
  291.                             lease.InitialLeaseTime = ilease.InitialLeaseTime;
  292.                             lease.RenewOnCallTime = ilease.RenewOnCallTime;
  293.                             lease.SponsorshipTimeout = ilease.SponsorshipTimeout;
  294.                         }
  295.                     }
  296.                     else {
  297.                         // An object of Type Lease was created
  298.                         BCLDebug.Trace("REMOTE", "LeaseLifeTimeServiceProperty.GetObjectSink, New Lease, lease is type Lease ", obj);
  299.                         lease = (Lease)ilease;
  300.                     }
  301.                    
  302.                     // Put lease in active state
  303.                     // Creation phase of lease is over, properties can no longer be set on lease.
  304.                     identity.Lease = lease;
  305.                     // Place lease into identity for object
  306.                     // If the object has been marshaled activate
  307.                     // the lease
  308.                     if (identity.ObjectRef != null) {
  309.                         lease.ActivateLease();
  310.                     }
  311.                 }
  312.             }
  313.            
  314.            
  315.             if (lease.RenewOnCallTime > TimeSpan.Zero) {
  316.                 // RenewOnCall create sink
  317.                 BCLDebug.Trace("REMOTE", "LeaseLifeTimeServiceProperty.GetObjectSink, lease created ", obj);
  318.                 return new LeaseSink(lease, nextSink);
  319.             }
  320.             else {
  321.                 // No RenewOnCall so no sink created
  322.                 BCLDebug.Trace("REMOTE", "LeaseLifeTimeServiceProperty.GetObjectSink, No RenewOnCall so no sink created ", obj);
  323.                 return nextSink;
  324.             }
  325.            
  326.         }
  327.        
  328.     }
  329.    
  330. }

Developer Fusion