Code:
/ FXUpdate3074 / FXUpdate3074 / 1.1 / untmp / whidbey / QFE / ndp / clr / src / BCL / System / Runtime / Remoting / Lease.cs / 2 / Lease.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== //+---------------------------------------------------------------------------- // // Microsoft Windows // File: Lease.cs // // Contents: Lease class // // History: 1/5/00[....] Created // //+--------------------------------------------------------------------------- namespace System.Runtime.Remoting.Lifetime { using System; using System.Security; using System.Security.Permissions; using System.Collections; using System.Threading; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Proxies; using System.Globalization; internal class Lease : MarshalByRefObject, ILease { internal int id = 0; // Lease Time internal DateTime leaseTime; internal TimeSpan initialLeaseTime; // Renewal Policies internal TimeSpan renewOnCallTime; internal TimeSpan sponsorshipTimeout; internal Boolean isInfinite = false; // Sponsors internal Hashtable sponsorTable; internal int sponsorCallThread; // Links to leasemanager and managed object internal LeaseManager leaseManager; internal MarshalByRefObject managedObject; // State internal LeaseState state; internal static int nextId = 0; internal Lease(TimeSpan initialLeaseTime, TimeSpan renewOnCallTime, TimeSpan sponsorshipTimeout, MarshalByRefObject managedObject ) { id = nextId++; BCLDebug.Trace("REMOTE", "Lease Constructor ",managedObject," initialLeaseTime "+initialLeaseTime+" renewOnCall "+renewOnCallTime+" sponsorshipTimeout ",sponsorshipTimeout); // Set Policy this.renewOnCallTime = renewOnCallTime; this.sponsorshipTimeout = sponsorshipTimeout; this.initialLeaseTime = initialLeaseTime; this.managedObject = managedObject; //Add lease to leaseManager leaseManager = LeaseManager.GetLeaseManager(); // Initialize tables sponsorTable = new Hashtable(10); state = LeaseState.Initial; } internal void ActivateLease() { // Set leaseTime leaseTime = DateTime.UtcNow.Add(initialLeaseTime); state = LeaseState.Active; leaseManager.ActivateLease(this); } // Override MarshalByRefObject InitializeLifetimeService // Don't want a lease on a lease therefore returns null public override Object InitializeLifetimeService() { BCLDebug.Trace("REMOTE", "Lease ",id," InitializeLifetimeService, lease Marshalled"); return null; } // ILease Property and Methods public TimeSpan RenewOnCallTime { get { return renewOnCallTime; } [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] set { if (state == LeaseState.Initial) { renewOnCallTime = value; BCLDebug.Trace("REMOTE", "Lease Set RenewOnCallProperty ",managedObject," "+renewOnCallTime); } else throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Lifetime_InitialStateRenewOnCall"), ((Enum)state).ToString())); } } public TimeSpan SponsorshipTimeout { get { return sponsorshipTimeout; } [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] set { if (state == LeaseState.Initial) { sponsorshipTimeout = value; BCLDebug.Trace("REMOTE", "Lease Set SponsorshipTimeout Property ",managedObject," "+sponsorshipTimeout); } else throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Lifetime_InitialStateSponsorshipTimeout"), ((Enum)state).ToString())); } } public TimeSpan InitialLeaseTime { get { return initialLeaseTime; } [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] set { if (state == LeaseState.Initial) { initialLeaseTime = value; if (TimeSpan.Zero.CompareTo(value) >= 0) state = LeaseState.Null; BCLDebug.Trace("REMOTE", "Lease Set InitialLeaseTime Property ",managedObject," "+InitialLeaseTime+", current state "+((Enum)state).ToString()); } else throw new RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_Lifetime_InitialStateInitialLeaseTime"), ((Enum)state).ToString())); } } public TimeSpan CurrentLeaseTime { get { return leaseTime.Subtract(DateTime.UtcNow); } } public LeaseState CurrentState { get { return state;} } [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] public void Register(ISponsor obj) { Register(obj, TimeSpan.Zero); } [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] public void Register(ISponsor obj, TimeSpan renewalTime) { lock(this) { BCLDebug.Trace("REMOTE", "Lease "+id+" Register Sponsor renewalTime ",renewalTime," state ",((Enum)state).ToString()); if (state == LeaseState.Expired || sponsorshipTimeout == TimeSpan.Zero) return; Object sponsorId = GetSponsorId(obj); lock(sponsorTable) { if (renewalTime > TimeSpan.Zero) AddTime(renewalTime); if (!sponsorTable.ContainsKey(sponsorId)) { // Place in tables sponsorTable[sponsorId] = new SponsorStateInfo(renewalTime, SponsorState.Initial); } } } } [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] public void Unregister(ISponsor sponsor) { lock(this) { BCLDebug.Trace("REMOTE", "Lease",id," Unregister state ",((Enum)state).ToString()); if (state == LeaseState.Expired) return; Object sponsorId = GetSponsorId(sponsor); lock(sponsorTable) { if (sponsorId != null) { leaseManager.DeleteSponsor(sponsorId); SponsorStateInfo sponsorStateInfo = (SponsorStateInfo)sponsorTable[sponsorId]; sponsorTable.Remove(sponsorId); } } } } // Get the local representative of the sponsor to prevent a remote access when placing // in a hash table. private Object GetSponsorId(ISponsor obj) { Object sponsorId = null; if (obj != null) { if (RemotingServices.IsTransparentProxy(obj)) sponsorId = RemotingServices.GetRealProxy(obj); else sponsorId = obj; } return sponsorId; } // Convert from the local representative of the sponsor to either the MarshalByRefObject or local object private ISponsor GetSponsorFromId(Object sponsorId) { Object sponsor = null; RealProxy rp = sponsorId as RealProxy; if (null != rp) sponsor = rp.GetTransparentProxy(); else sponsor = sponsorId; return (ISponsor)sponsor; } [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.RemotingConfiguration)] public TimeSpan Renew(TimeSpan renewalTime) { return RenewInternal(renewalTime); } // We will call this internally within the server domain internal TimeSpan RenewInternal(TimeSpan renewalTime) { lock(this) { BCLDebug.Trace("REMOTE","Lease ",id," Renew ",renewalTime," state ",((Enum)state).ToString()); if (state == LeaseState.Expired) return TimeSpan.Zero; AddTime(renewalTime); return leaseTime.Subtract(DateTime.UtcNow); } } // Used for a lease which has been created, but will not be used internal void Remove() { BCLDebug.Trace("REMOTE","Lease ",id," Remove state ",((Enum)state).ToString()); if (state == LeaseState.Expired) return; state = LeaseState.Expired; leaseManager.DeleteLease(this); } internal void Cancel() { lock(this) { BCLDebug.Trace("REMOTE","Lease ",id," Cancel Managed Object ",managedObject," state ",((Enum)state).ToString()); if (state == LeaseState.Expired) return; Remove(); // Disconnect the object ... // We use the internal version of Disconnect passign "false" // for the bResetURI flag. This allows the object to keep its // old URI in case its lease gets reactivated later. RemotingServices.Disconnect(managedObject, false); // Disconnect the lease for the object. RemotingServices.Disconnect(this); } } #if _DEBUG ~Lease() { BCLDebug.Trace("REMOTE","Lease ",id," Finalize"); } #endif internal void RenewOnCall() { lock(this) { //BCLDebug.Trace("REMOTE","Lease ",id," RenewOnCall state ",((Enum)state).ToString()); if (state == LeaseState.Initial || state == LeaseState.Expired) return; AddTime(renewOnCallTime); } } internal void LeaseExpired(DateTime now) { lock(this) { BCLDebug.Trace("REMOTE","Lease ",id," LeaseExpired state ",((Enum)state).ToString()); if (state == LeaseState.Expired) return; // There is a small window between the time the leaseManager // thread examines all the leases and tests for expiry and // when an indivisual lease is locked for expiry. The object // could get marshal-ed in this time which would reset its lease // Therefore we if (leaseTime.CompareTo(now) < 0) ProcessNextSponsor(); } } internal delegate TimeSpan AsyncRenewal(ILease lease); internal void SponsorCall(ISponsor sponsor) { BCLDebug.Trace("REMOTE","Lease ",id," SponsorCall state ",((Enum)state).ToString()); bool exceptionOccurred = false; if (state == LeaseState.Expired) return; lock(sponsorTable) { try { Object sponsorId = GetSponsorId(sponsor); sponsorCallThread = Thread.CurrentThread.GetHashCode(); AsyncRenewal ar = new AsyncRenewal(sponsor.Renewal); SponsorStateInfo sponsorStateInfo = (SponsorStateInfo)sponsorTable[sponsorId]; sponsorStateInfo.sponsorState = SponsorState.Waiting; // The first parameter should be the lease we are trying to renew. IAsyncResult iar = ar.BeginInvoke(this, new AsyncCallback(this.SponsorCallback), null); if ((sponsorStateInfo.sponsorState == SponsorState.Waiting) && (state != LeaseState.Expired)) { // Even if we get here, the operation could still complete before // we call the the line below. This seems to be a race. // Sponsor could have completed before statement is reached, so only execute // if the sponsor state is still waiting leaseManager.RegisterSponsorCall(this, sponsorId, sponsorshipTimeout); } sponsorCallThread = 0; }catch(Exception) { // Sponsor not avaiable exceptionOccurred = true; sponsorCallThread = 0; } } if (exceptionOccurred) { BCLDebug.Trace("REMOTE","Lease ",id," SponsorCall Sponsor Exception "); Unregister(sponsor); ProcessNextSponsor(); } } internal void SponsorTimeout(Object sponsorId) { lock (this) { if (!sponsorTable.ContainsKey(sponsorId)) return; lock(sponsorTable) { SponsorStateInfo sponsorStateInfo = (SponsorStateInfo)sponsorTable[sponsorId]; BCLDebug.Trace("REMOTE","Lease ",id," SponsorTimeout sponsorState ",((Enum)sponsorStateInfo.sponsorState).ToString()); if (sponsorStateInfo.sponsorState == SponsorState.Waiting) { Unregister(GetSponsorFromId(sponsorId)); ProcessNextSponsor(); } } } } private void ProcessNextSponsor() { BCLDebug.Trace("REMOTE","Lease ",id," ProcessNextSponsor"); Object largestSponsor = null; TimeSpan largestRenewalTime = TimeSpan.Zero; lock(sponsorTable) { IDictionaryEnumerator e = sponsorTable.GetEnumerator(); // Find sponsor with largest previous renewal value while(e.MoveNext()) { Object sponsorId = e.Key; SponsorStateInfo sponsorStateInfo = (SponsorStateInfo)e.Value; if ((sponsorStateInfo.sponsorState == SponsorState.Initial) && (largestRenewalTime == TimeSpan.Zero)) { largestRenewalTime = sponsorStateInfo.renewalTime; largestSponsor = sponsorId; } else if (sponsorStateInfo.renewalTime > largestRenewalTime) { largestRenewalTime = sponsorStateInfo.renewalTime; largestSponsor = sponsorId; } } } if (largestSponsor != null) SponsorCall(GetSponsorFromId(largestSponsor)); else { // No more sponsors to try, Cancel BCLDebug.Trace("REMOTE","Lease ",id," ProcessNextSponsor no more sponsors"); Cancel(); } } // This gets called when we explicitly transfer the call back from the // called function to a threadpool thread. internal void SponsorCallback(Object obj) { SponsorCallback((IAsyncResult)obj); } // On another thread internal void SponsorCallback(IAsyncResult iar) { BCLDebug.Trace("REMOTE","Lease ",id," SponsorCallback IAsyncResult ",iar," state ",((Enum)state).ToString()); if (state == LeaseState.Expired) { return; } int thisThread = Thread.CurrentThread.GetHashCode(); if (thisThread == sponsorCallThread) { // Looks like something went wrong and the thread that // did the AsyncRenewal::BeginInvoke is executing the callback // We will queue the work to the thread pool (otherwise there // is a possibility of stack overflow if all sponsors are down) WaitCallback threadFunc = new WaitCallback(this.SponsorCallback); ThreadPool.QueueUserWorkItem(threadFunc, iar); return; } AsyncResult asyncResult = (AsyncResult)iar; AsyncRenewal ar = (AsyncRenewal)asyncResult.AsyncDelegate; ISponsor sponsor = (ISponsor)ar.Target; SponsorStateInfo sponsorStateInfo = null; if (iar.IsCompleted) { // Sponsor came back with renewal BCLDebug.Trace("REMOTE","Lease ",id," SponsorCallback sponsor completed"); bool exceptionOccurred = false; TimeSpan renewalTime = TimeSpan.Zero; try { renewalTime = (TimeSpan)ar.EndInvoke(iar); }catch(Exception) { // Sponsor not avaiable exceptionOccurred = true; } if (exceptionOccurred) { BCLDebug.Trace("REMOTE","Lease ",id," SponsorCallback Sponsor Exception "); Unregister(sponsor); ProcessNextSponsor(); } else { Object sponsorId = GetSponsorId(sponsor); lock(sponsorTable) { if (sponsorTable.ContainsKey(sponsorId)) { sponsorStateInfo = (SponsorStateInfo)sponsorTable[sponsorId]; sponsorStateInfo.sponsorState = SponsorState.Completed; sponsorStateInfo.renewalTime = renewalTime; } else { // Sponsor was deleted, possibly from a sponsor time out } } if (sponsorStateInfo == null) { // Sponsor was deleted ProcessNextSponsor(); } else if (sponsorStateInfo.renewalTime == TimeSpan.Zero) { BCLDebug.Trace("REMOTE","Lease ",id," SponsorCallback sponsor did not renew "); Unregister(sponsor); ProcessNextSponsor(); } else RenewInternal(sponsorStateInfo.renewalTime); } } else { // Sponsor timed out // Note time outs should be handled by the LeaseManager BCLDebug.Trace("REMOTE","Lease ",id," SponsorCallback sponsor did not complete, timed out"); Unregister(sponsor); ProcessNextSponsor(); } } private void AddTime(TimeSpan renewalSpan) { if (state == LeaseState.Expired) return; DateTime now = DateTime.UtcNow; DateTime oldLeaseTime = leaseTime; DateTime renewTime = now.Add(renewalSpan); if (leaseTime.CompareTo(renewTime) < 0) { leaseManager.ChangedLeaseTime(this, renewTime); leaseTime = renewTime; state = LeaseState.Active; } //BCLDebug.Trace("REMOTE","Lease ",id," AddTime renewalSpan ",renewalSpan," current Time ",now," old leaseTime ",oldLeaseTime," new leaseTime ",leaseTime," state ",((Enum)state).ToString()); } [Serializable] internal enum SponsorState { Initial = 0, Waiting = 1, Completed = 2 } internal sealed class SponsorStateInfo { internal TimeSpan renewalTime; internal SponsorState sponsorState; internal SponsorStateInfo(TimeSpan renewalTime, SponsorState sponsorState) { this.renewalTime = renewalTime; this.sponsorState = sponsorState; } } } internal class LeaseSink : IMessageSink { Lease lease = null; IMessageSink nextSink = null; public LeaseSink(Lease lease, IMessageSink nextSink) { this.lease = lease; this.nextSink = nextSink; } //IMessageSink methods public IMessage SyncProcessMessage(IMessage msg) { //BCLDebug.Trace("REMOTE","Lease ",id," SyncProcessMessage"); lease.RenewOnCall(); return nextSink.SyncProcessMessage(msg); } public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink) { //BCLDebug.Trace("REMOTE","Lease ",id," AsyncProcessMessage"); lease.RenewOnCall(); return nextSink.AsyncProcessMessage(msg, replySink); } public IMessageSink NextSink { get { //BCLDebug.Trace("REMOTE","Lease ",id," NextSink"); return nextSink; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- recordstatefactory.cs
- SafeSerializationManager.cs
- DeobfuscatingStream.cs
- NextPreviousPagerField.cs
- QueryContinueDragEventArgs.cs
- PageCatalogPartDesigner.cs
- BitmapImage.cs
- AsymmetricKeyExchangeFormatter.cs
- WorkflowServiceOperationListItem.cs
- SetterTriggerConditionValueConverter.cs
- CustomValidator.cs
- CodePageEncoding.cs
- SqlBuffer.cs
- ModelItemKeyValuePair.cs
- HttpRuntime.cs
- DataGridViewButtonColumn.cs
- JumpPath.cs
- HotSpotCollection.cs
- HostSecurityManager.cs
- ClosableStream.cs
- TraceListeners.cs
- GridViewRowCollection.cs
- DependencyObjectType.cs
- BooleanFunctions.cs
- PopOutPanel.cs
- XamlRtfConverter.cs
- DataGridViewCellErrorTextNeededEventArgs.cs
- XamlSerializer.cs
- PrintPreviewGraphics.cs
- X509WindowsSecurityToken.cs
- MultiTrigger.cs
- BooleanProjectedSlot.cs
- AsnEncodedData.cs
- RectangleHotSpot.cs
- CqlParser.cs
- CodeLabeledStatement.cs
- RadioButtonPopupAdapter.cs
- TypeLoadException.cs
- PersistenceTypeAttribute.cs
- MaskInputRejectedEventArgs.cs
- SmtpReplyReader.cs
- Debug.cs
- HttpCachePolicy.cs
- Polygon.cs
- XPathMessageFilterElementCollection.cs
- WebBrowserNavigatingEventHandler.cs
- RolePrincipal.cs
- ConnectionPointCookie.cs
- LineVisual.cs
- AdvancedBindingPropertyDescriptor.cs
- TextElementEditingBehaviorAttribute.cs
- SafeUserTokenHandle.cs
- RemotingClientProxy.cs
- SettingsContext.cs
- CutCopyPasteHelper.cs
- DropShadowBitmapEffect.cs
- UnsafeNetInfoNativeMethods.cs
- OptimizerPatterns.cs
- Unit.cs
- XsltException.cs
- basecomparevalidator.cs
- SqlStream.cs
- DoubleKeyFrameCollection.cs
- XmlQuerySequence.cs
- JoinElimination.cs
- PrivacyNoticeBindingElement.cs
- SqlReferenceCollection.cs
- DbDataSourceEnumerator.cs
- SafeNativeMethods.cs
- ReadOnlyKeyedCollection.cs
- DataGridViewAutoSizeColumnModeEventArgs.cs
- DrawTreeNodeEventArgs.cs
- X509Certificate2.cs
- EventMetadata.cs
- ObjectSet.cs
- BasicKeyConstraint.cs
- OleCmdHelper.cs
- CounterSample.cs
- SQLBytes.cs
- ACE.cs
- PersistenceMetadataNamespace.cs
- XPathParser.cs
- PluralizationService.cs
- FileUtil.cs
- IssuedSecurityTokenProvider.cs
- MetadataProperty.cs
- WorkflowInstanceExtensionProvider.cs
- KeysConverter.cs
- XmlSerializer.cs
- AnonymousIdentificationModule.cs
- TrackingParameters.cs
- NTAccount.cs
- CodeNamespaceImport.cs
- XsdDateTime.cs
- BindingCollection.cs
- CqlGenerator.cs
- FixedPosition.cs
- Simplifier.cs
- DrawingContext.cs
- InfoCardRequestException.cs