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

  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: LeaseManager.cs
  19. //
  20. // Contents: Administers the leases in an appdomain
  21. //
  22. // History: 1/5/00 Created
  23. //
  24. //+----------------------------------------------------------------------------
  25. namespace System.Runtime.Remoting.Lifetime
  26. {
  27.     using System;
  28.     using System.Collections;
  29.     using System.Threading;
  30.    
  31.     internal class LeaseManager
  32.     {
  33.        
  34.         // Lease Lists
  35.         private Hashtable leaseToTimeTable = new Hashtable();
  36.        
  37.         // Async Sponsor Calls
  38.         //private SortedList sponsorCallList = new SortedList();
  39.         private Hashtable sponsorTable = new Hashtable();
  40.        
  41.        
  42.         // LeaseTimeAnalyzer thread
  43.         private TimeSpan pollTime;
  44.         AutoResetEvent waitHandle;
  45.         TimerCallback leaseTimeAnalyzerDelegate;
  46.         private volatile Timer leaseTimer;
  47.        
  48.        
  49.         static internal bool IsInitialized()
  50.         {
  51.             DomainSpecificRemotingData remotingData = Thread.GetDomain().RemotingData;
  52.             LeaseManager leaseManager = remotingData.LeaseManager;
  53.             return leaseManager != null;
  54.         }
  55.        
  56.         static internal LeaseManager GetLeaseManager(TimeSpan pollTime)
  57.         {
  58.             DomainSpecificRemotingData remotingData = Thread.GetDomain().RemotingData;
  59.             LeaseManager leaseManager = remotingData.LeaseManager;
  60.             if (leaseManager == null) {
  61.                 lock (remotingData) {
  62.                     if (remotingData.LeaseManager == null) {
  63.                         remotingData.LeaseManager = new LeaseManager(pollTime);
  64.                     }
  65.                     leaseManager = remotingData.LeaseManager;
  66.                 }
  67.             }
  68.            
  69.             return leaseManager;
  70.         }
  71.        
  72.         static internal LeaseManager GetLeaseManager()
  73.         {
  74.             DomainSpecificRemotingData remotingData = Thread.GetDomain().RemotingData;
  75.             LeaseManager leaseManager = remotingData.LeaseManager;
  76.             BCLDebug.Assert(leaseManager != null, "[LeaseManager.GetLeaseManager()]leaseManager !=null");
  77.             return leaseManager;
  78.         }
  79.        
  80.        
  81.         private LeaseManager(TimeSpan pollTime)
  82.         {
  83.             BCLDebug.Trace("REMOTE", "LeaseManager Constructor");
  84.             this.pollTime = pollTime;
  85.            
  86.             leaseTimeAnalyzerDelegate = new TimerCallback(this.LeaseTimeAnalyzer);
  87.             waitHandle = new AutoResetEvent(false);
  88.             // We need to create a Timer with Infinite dueTime to ensure that
  89.             // leaseTimeAnalyzerDelegate doesnt get invoked before leaseTimer is initialized
  90.             // Once initialized we can change it to the appropriate dueTime
  91.             leaseTimer = new Timer(leaseTimeAnalyzerDelegate, null, Timeout.Infinite, Timeout.Infinite);
  92.             leaseTimer.Change((int)pollTime.TotalMilliseconds, Timeout.Infinite);
  93.         }
  94.        
  95.        
  96.         internal void ChangePollTime(TimeSpan pollTime)
  97.         {
  98.             BCLDebug.Trace("REMOTE", "LeaseManager ChangePollTime ", pollTime);
  99.             this.pollTime = pollTime;
  100.         }
  101.        
  102.        
  103.         internal void ActivateLease(Lease lease)
  104.         {
  105.             BCLDebug.Trace("REMOTE", "LeaseManager AddLease ", lease.id, " ", lease.managedObject);
  106.             lock (leaseToTimeTable) {
  107.                 leaseToTimeTable[lease] = lease.leaseTime;
  108.             }
  109.         }
  110.        
  111.         internal void DeleteLease(Lease lease)
  112.         {
  113.             BCLDebug.Trace("REMOTE", "LeaseManager DeleteLease ", lease.id);
  114.             lock (leaseToTimeTable) {
  115.                 leaseToTimeTable.Remove(lease);
  116.             }
  117.         }
  118.        
  119.         [System.Diagnostics.Conditional("_LOGGING")]
  120.         internal void DumpLeases(Lease[] leases)
  121.         {
  122.             for (int i = 0; i < leases.Length; i++) {
  123.                 BCLDebug.Trace("REMOTE", "LeaseManager DumpLease ", leases[i].managedObject);
  124.             }
  125.         }
  126.        
  127.        
  128.         internal ILease GetLease(MarshalByRefObject obj)
  129.         {
  130.             BCLDebug.Trace("REMOTE", "LeaseManager GetLease ", obj);
  131.             bool fServer = true;
  132.             Identity idObj = MarshalByRefObject.GetIdentity(obj, out fServer);
  133.             if (idObj == null)
  134.                 return null;
  135.             else
  136.                 return idObj.Lease;
  137.         }
  138.        
  139.         internal void ChangedLeaseTime(Lease lease, DateTime newTime)
  140.         {
  141.             BCLDebug.Trace("REMOTE", "LeaseManager ChangedLeaseTime ", lease.id, " ", lease.managedObject, " newTime ", newTime, " currentTime ", DateTime.UtcNow);
  142.             lock (leaseToTimeTable) {
  143.                 leaseToTimeTable[lease] = newTime;
  144.             }
  145.         }
  146.        
  147.         internal class SponsorInfo
  148.         {
  149.             internal Lease lease;
  150.             internal object sponsorId;
  151.             internal DateTime sponsorWaitTime;
  152.            
  153.             internal SponsorInfo(Lease lease, object sponsorId, DateTime sponsorWaitTime)
  154.             {
  155.                 this.lease = lease;
  156.                 this.sponsorId = sponsorId;
  157.                 this.sponsorWaitTime = sponsorWaitTime;
  158.             }
  159.         }
  160.        
  161.         internal void RegisterSponsorCall(Lease lease, object sponsorId, TimeSpan sponsorshipTimeOut)
  162.         {
  163.             BCLDebug.Trace("REMOTE", "LeaseManager RegisterSponsorCall Lease ", lease, " sponsorshipTimeOut ", sponsorshipTimeOut);
  164.            
  165.             lock (sponsorTable) {
  166.                 DateTime sponsorWaitTime = DateTime.UtcNow.Add(sponsorshipTimeOut);
  167.                 sponsorTable[sponsorId] = new SponsorInfo(lease, sponsorId, sponsorWaitTime);
  168.             }
  169.         }
  170.        
  171.         internal void DeleteSponsor(object sponsorId)
  172.         {
  173.             lock (sponsorTable) {
  174.                 sponsorTable.Remove(sponsorId);
  175.             }
  176.         }
  177.        
  178.         ArrayList tempObjects = new ArrayList(10);
  179.        
  180.         // Thread Loop
  181.         private void LeaseTimeAnalyzer(object state)
  182.         {
  183.             //BCLDebug.Trace("REMOTE","LeaseManager LeaseTimeAnalyzer Entry ",state);
  184.            
  185.             // Find expired leases
  186.             DateTime now = DateTime.UtcNow;
  187.             lock (leaseToTimeTable) {
  188.                 IDictionaryEnumerator e = leaseToTimeTable.GetEnumerator();
  189.                
  190.                 while (e.MoveNext()) {
  191.                     DateTime time = (DateTime)e.Value;
  192.                     Lease lease = (Lease)e.Key;
  193.                     //BCLDebug.Trace("REMOTE","LeaseManager LeaseTimeAnalyzer lease ",lease.id, " lease time ", time, " now ", now);
  194.                     if (time.CompareTo(now) < 0) {
  195.                         // lease expired
  196.                         tempObjects.Add(lease);
  197.                     }
  198.                 }
  199.                 for (int i = 0; i < tempObjects.Count; i++) {
  200.                     Lease lease = (Lease)tempObjects[i];
  201.                     //BCLDebug.Trace("REMOTE","LeaseManager LeaseTimeAnalyzer lease Expired remove from leaseToTimeTable ",lease.id);
  202.                     leaseToTimeTable.Remove(lease);
  203.                 }
  204.                
  205.             }
  206.            
  207.             // Need to run this without lock on leaseToTimeTable to avoid deadlock
  208.             for (int i = 0; i < tempObjects.Count; i++) {
  209.                 Lease lease = (Lease)tempObjects[i];
  210.                 //BCLDebug.Trace("REMOTE","LeaseManager LeaseTimeAnalyzer lease Expired ",lease.id);
  211.                 if (lease != null)
  212.                     // Lease could be deleted if there is more then one reference to the lease
  213.                     lease.LeaseExpired(now);
  214.             }
  215.            
  216.             tempObjects.Clear();
  217.            
  218.             lock (sponsorTable) {
  219.                 IDictionaryEnumerator e = sponsorTable.GetEnumerator();
  220.                
  221.                 while (e.MoveNext()) {
  222.                     // Check for SponshipTimeOuts
  223.                     object sponsorId = e.Key;
  224.                     SponsorInfo sponsorInfo = (SponsorInfo)e.Value;
  225.                     //BCLDebug.Trace("REMOTE","LeaseManager LeaseTimeAnalyzer sponsor time ", sponsorInfo.sponsorWaitTime, " now ", now);
  226.                     if (sponsorInfo.sponsorWaitTime.CompareTo(now) < 0) {
  227.                         // Sponsortimeout expired expired
  228.                         tempObjects.Add(sponsorInfo);
  229.                     }
  230.                 }
  231.                
  232.                 // Process the timed out sponsors
  233.                 for (int i = 0; i < tempObjects.Count; i++) {
  234.                     SponsorInfo sponsorInfo = (SponsorInfo)tempObjects[i];
  235.                     //BCLDebug.Trace("REMOTE","LeaseManager LeaseTimeAnalyzer sponsor Expired remove from spansorTable", sponsorInfo.sponsorId);
  236.                     sponsorTable.Remove(sponsorInfo.sponsorId);
  237.                 }
  238.             }
  239.            
  240.             // Process the timed out sponsors
  241.             // Need to run this without lock on sponsorTable to avoid deadlock
  242.             for (int i = 0; i < tempObjects.Count; i++) {
  243.                 SponsorInfo sponsorInfo = (SponsorInfo)tempObjects[i];
  244.                 //BCLDebug.Trace("REMOTE","LeaseManager LeaseTimeAnalyzer sponsor Expired ", sponsorInfo.sponsorId);
  245.                 if (sponsorInfo != null && sponsorInfo.lease != null) {
  246.                     sponsorInfo.lease.SponsorTimeout(sponsorInfo.sponsorId);
  247.                     tempObjects[i] = null;
  248.                 }
  249.             }
  250.            
  251.             tempObjects.Clear();
  252.             leaseTimer.Change((int)pollTime.TotalMilliseconds, Timeout.Infinite);
  253.            
  254.             //BCLDebug.Trace("REMOTE","LeaseManager LeaseTimeAnalyzer Exit");
  255.         }
  256.        
  257.     }
  258. }

Developer Fusion