Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / clr / src / BCL / System / Runtime / Remoting / ServerIdentity.cs / 1 / ServerIdentity.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== namespace System.Runtime.Remoting { using System; using System.Collections; using System.Threading; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Proxies; using System.Runtime.ConstrainedExecution; using System.Runtime.CompilerServices; using System.Globalization; // ServerIdentity derives from Identity and holds the extra server specific information // associated with each instance of a remoted server object. // internal class ServerIdentity : Identity { // Internal members internal Context _srvCtx; // This is used to cache the last server type private class LastCalledType { public String typeName; public Type type; } // These two fields are used for (purely) MarshalByRef object identities // For context bound objects we have corresponding fields in RemotingProxy // that are used instead. This is done to facilitate GC in x-context cases. internal IMessageSink _serverObjectChain; internal StackBuilderSink _stackBuilderSink; // This manages the dynamic properties registered on per object/proxy basis internal DynamicPropertyHolder _dphSrv; internal Type _srvType; // type of server object private LastCalledType _lastCalledType; // cache the last type object internal bool _bMarshaledAsSpecificType = false; internal int _firstCallDispatched = 0; internal GCHandle _srvIdentityHandle; internal Type GetLastCalledType(String newTypeName) { LastCalledType lastType = _lastCalledType; if (lastType == null) return null; String typeName = lastType.typeName; Type t = lastType.type; if (typeName==null || t==null) return null; if (typeName.Equals(newTypeName)) return t; return null; } // GetLastCalledMethod internal void SetLastCalledType(String newTypeName, Type newType) { LastCalledType lastType = new LastCalledType(); lastType.typeName = newTypeName; lastType.type = newType; _lastCalledType = lastType; } // SetLastCalledMethod internal void SetHandle() { bool fLocked = false; RuntimeHelpers.PrepareConstrainedRegions(); try { Monitor.ReliableEnter(this, ref fLocked); if (!_srvIdentityHandle.IsAllocated) _srvIdentityHandle = new GCHandle(this, GCHandleType.Normal); else _srvIdentityHandle.Target = this; } finally { if (fLocked) { Monitor.Exit(this); } } } internal void ResetHandle() { bool fLocked = false; RuntimeHelpers.PrepareConstrainedRegions(); try { Monitor.ReliableEnter(this, ref fLocked); _srvIdentityHandle.Target = null; } finally { if (fLocked) { Monitor.Exit(this); } } } internal GCHandle GetHandle() { return _srvIdentityHandle; } // Creates a new server identity. This form is used by RemotingServices.Wrap // internal ServerIdentity(MarshalByRefObject obj, Context serverCtx) : base(obj is ContextBoundObject) { if(null != obj) { if(!RemotingServices.IsTransparentProxy(obj)) { _srvType = obj.GetType(); } else { RealProxy rp = RemotingServices.GetRealProxy(obj); _srvType = rp.GetProxiedType(); } } _srvCtx = serverCtx; _serverObjectChain = null; _stackBuilderSink = null; } // This is used by RS::SetObjectUriForMarshal internal ServerIdentity(MarshalByRefObject obj, Context serverCtx, String uri) : this(obj, serverCtx) { SetOrCreateURI(uri, true); // calling from the constructor } // Informational methods on the ServerIdentity. // Get the native context for the server object. internal Context ServerContext { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] get {return _srvCtx;} } internal void SetSingleCallObjectMode() { BCLDebug.Assert( !IsSingleCall() && !IsSingleton(), "Bad serverID"); _flags |= IDFLG_SERVER_SINGLECALL; } internal void SetSingletonObjectMode() { BCLDebug.Assert( !IsSingleCall() && !IsSingleton(), "Bad serverID"); _flags |= IDFLG_SERVER_SINGLETON; } internal bool IsSingleCall() { return ((_flags&IDFLG_SERVER_SINGLECALL) != 0); } internal bool IsSingleton() { return ((_flags&IDFLG_SERVER_SINGLETON) != 0); } internal IMessageSink GetServerObjectChain(out MarshalByRefObject obj) { obj = null; // NOTE: Lifetime relies on the Identity flags for // SingleCall and Singleton being set by the time this getter // is called. if (!this.IsSingleCall()) { // This is the common case if (_serverObjectChain == null) { bool fLocked = false; RuntimeHelpers.PrepareConstrainedRegions(); try { Monitor.ReliableEnter(this, ref fLocked); if(_serverObjectChain == null) { MarshalByRefObject srvObj = (MarshalByRefObject) this.TPOrObject; _serverObjectChain = _srvCtx.CreateServerObjectChain( srvObj); } } finally { if (fLocked) { Monitor.Exit(this); } } } BCLDebug.Assert( null != _serverObjectChain, "null != _serverObjectChain"); return _serverObjectChain; } else { // ---------- SINGLE CALL WKO -------------- // In this case, we are expected to provide // a fresh server object for each dispatch. // Since the server object chain is object // specific, we must create a fresh chain too. // We must be in the correct context for this // to succeed. // < BCLDebug.Assert(Thread.CurrentContext==_srvCtx, "Bad context mismatch"); MarshalByRefObject srvObj = null; IMessageSink objChain = null; if (_tpOrObject != null && _firstCallDispatched == 0 && Interlocked.CompareExchange(ref _firstCallDispatched, 1, 0) == 0) { // use the instance of server object created to // set up the pipeline. srvObj = (MarshalByRefObject) _tpOrObject; objChain = _serverObjectChain; if (objChain == null) { objChain = _srvCtx.CreateServerObjectChain(srvObj); } } else { // For singleCall we create a fresh object & its chain // on each dispatch! srvObj = (MarshalByRefObject) Activator.CreateInstance((Type)_srvType, true); // make sure that object didn't Marshal itself. // (well known objects should live up to their promise // of exporting themselves through exactly one url) String tempUri = RemotingServices.GetObjectUri(srvObj); if (tempUri != null) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_WellKnown_CtorCantMarshal"), this.URI)); } // Set the identity depending on whether we have the server // or proxy if(!RemotingServices.IsTransparentProxy(srvObj)) { #if _DEBUG Identity idObj = srvObj.__RaceSetServerIdentity(this); #else srvObj.__RaceSetServerIdentity(this); #endif #if _DEBUG BCLDebug.Assert(idObj == this, "Bad ID state!" ); BCLDebug.Assert(idObj == MarshalByRefObject.GetIdentity(srvObj), "Bad ID state!" ); #endif } else { RealProxy rp = null; rp = RemotingServices.GetRealProxy(srvObj); BCLDebug.Assert(null != rp, "null != rp"); // #if _DEBUG // Identity idObj = (ServerIdentity) rp.SetIdentity(this); // #else rp.IdentityObject = this; // #endif #if false #if _DEBUG // #endif #endif } // Create the object chain and return it objChain = _srvCtx.CreateServerObjectChain(srvObj); } // This is passed out to the caller so that for single-call // case we can call Dispose when the incoming call is done obj = srvObj; return objChain; } } internal Type ServerType { get { return _srvType; } set { _srvType = value; } } // ServerType internal bool MarshaledAsSpecificType { get { return _bMarshaledAsSpecificType; } set { _bMarshaledAsSpecificType = value; } } // MarshaledAsSpecificType internal IMessageSink RaceSetServerObjectChain( IMessageSink serverObjectChain) { if (_serverObjectChain == null) { bool fLocked = false; RuntimeHelpers.PrepareConstrainedRegions(); try { Monitor.ReliableEnter(this, ref fLocked); if (_serverObjectChain == null) { _serverObjectChain = serverObjectChain; } } finally { if (fLocked) { Monitor.Exit(this); } } } return _serverObjectChain; } /*package*/ internal bool AddServerSideDynamicProperty( IDynamicProperty prop) { if (_dphSrv == null) { DynamicPropertyHolder dphSrv = new DynamicPropertyHolder(); bool fLocked = false; RuntimeHelpers.PrepareConstrainedRegions(); try { Monitor.ReliableEnter(this, ref fLocked); if (_dphSrv == null) { _dphSrv = dphSrv; } } finally { if (fLocked) { Monitor.Exit(this); } } } return _dphSrv.AddDynamicProperty(prop); } /*package*/ internal bool RemoveServerSideDynamicProperty(String name) { if (_dphSrv == null) { throw new ArgumentException(Environment.GetResourceString("Arg_PropNotFound") ); } return _dphSrv.RemoveDynamicProperty(name); } internal ArrayWithSize ServerSideDynamicSinks { get { if (_dphSrv == null) { return null; } else { return _dphSrv.DynamicSinks; } } } internal override void AssertValid() { base.AssertValid(); if((null != this.TPOrObject) && !RemotingServices.IsTransparentProxy(this.TPOrObject)) { BCLDebug.Assert(MarshalByRefObject.GetIdentity((MarshalByRefObject)this.TPOrObject) == this, "Server ID mismatch with Object"); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== namespace System.Runtime.Remoting { using System; using System.Collections; using System.Threading; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Proxies; using System.Runtime.ConstrainedExecution; using System.Runtime.CompilerServices; using System.Globalization; // ServerIdentity derives from Identity and holds the extra server specific information // associated with each instance of a remoted server object. // internal class ServerIdentity : Identity { // Internal members internal Context _srvCtx; // This is used to cache the last server type private class LastCalledType { public String typeName; public Type type; } // These two fields are used for (purely) MarshalByRef object identities // For context bound objects we have corresponding fields in RemotingProxy // that are used instead. This is done to facilitate GC in x-context cases. internal IMessageSink _serverObjectChain; internal StackBuilderSink _stackBuilderSink; // This manages the dynamic properties registered on per object/proxy basis internal DynamicPropertyHolder _dphSrv; internal Type _srvType; // type of server object private LastCalledType _lastCalledType; // cache the last type object internal bool _bMarshaledAsSpecificType = false; internal int _firstCallDispatched = 0; internal GCHandle _srvIdentityHandle; internal Type GetLastCalledType(String newTypeName) { LastCalledType lastType = _lastCalledType; if (lastType == null) return null; String typeName = lastType.typeName; Type t = lastType.type; if (typeName==null || t==null) return null; if (typeName.Equals(newTypeName)) return t; return null; } // GetLastCalledMethod internal void SetLastCalledType(String newTypeName, Type newType) { LastCalledType lastType = new LastCalledType(); lastType.typeName = newTypeName; lastType.type = newType; _lastCalledType = lastType; } // SetLastCalledMethod internal void SetHandle() { bool fLocked = false; RuntimeHelpers.PrepareConstrainedRegions(); try { Monitor.ReliableEnter(this, ref fLocked); if (!_srvIdentityHandle.IsAllocated) _srvIdentityHandle = new GCHandle(this, GCHandleType.Normal); else _srvIdentityHandle.Target = this; } finally { if (fLocked) { Monitor.Exit(this); } } } internal void ResetHandle() { bool fLocked = false; RuntimeHelpers.PrepareConstrainedRegions(); try { Monitor.ReliableEnter(this, ref fLocked); _srvIdentityHandle.Target = null; } finally { if (fLocked) { Monitor.Exit(this); } } } internal GCHandle GetHandle() { return _srvIdentityHandle; } // Creates a new server identity. This form is used by RemotingServices.Wrap // internal ServerIdentity(MarshalByRefObject obj, Context serverCtx) : base(obj is ContextBoundObject) { if(null != obj) { if(!RemotingServices.IsTransparentProxy(obj)) { _srvType = obj.GetType(); } else { RealProxy rp = RemotingServices.GetRealProxy(obj); _srvType = rp.GetProxiedType(); } } _srvCtx = serverCtx; _serverObjectChain = null; _stackBuilderSink = null; } // This is used by RS::SetObjectUriForMarshal internal ServerIdentity(MarshalByRefObject obj, Context serverCtx, String uri) : this(obj, serverCtx) { SetOrCreateURI(uri, true); // calling from the constructor } // Informational methods on the ServerIdentity. // Get the native context for the server object. internal Context ServerContext { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] get {return _srvCtx;} } internal void SetSingleCallObjectMode() { BCLDebug.Assert( !IsSingleCall() && !IsSingleton(), "Bad serverID"); _flags |= IDFLG_SERVER_SINGLECALL; } internal void SetSingletonObjectMode() { BCLDebug.Assert( !IsSingleCall() && !IsSingleton(), "Bad serverID"); _flags |= IDFLG_SERVER_SINGLETON; } internal bool IsSingleCall() { return ((_flags&IDFLG_SERVER_SINGLECALL) != 0); } internal bool IsSingleton() { return ((_flags&IDFLG_SERVER_SINGLETON) != 0); } internal IMessageSink GetServerObjectChain(out MarshalByRefObject obj) { obj = null; // NOTE: Lifetime relies on the Identity flags for // SingleCall and Singleton being set by the time this getter // is called. if (!this.IsSingleCall()) { // This is the common case if (_serverObjectChain == null) { bool fLocked = false; RuntimeHelpers.PrepareConstrainedRegions(); try { Monitor.ReliableEnter(this, ref fLocked); if(_serverObjectChain == null) { MarshalByRefObject srvObj = (MarshalByRefObject) this.TPOrObject; _serverObjectChain = _srvCtx.CreateServerObjectChain( srvObj); } } finally { if (fLocked) { Monitor.Exit(this); } } } BCLDebug.Assert( null != _serverObjectChain, "null != _serverObjectChain"); return _serverObjectChain; } else { // ---------- SINGLE CALL WKO -------------- // In this case, we are expected to provide // a fresh server object for each dispatch. // Since the server object chain is object // specific, we must create a fresh chain too. // We must be in the correct context for this // to succeed. // < BCLDebug.Assert(Thread.CurrentContext==_srvCtx, "Bad context mismatch"); MarshalByRefObject srvObj = null; IMessageSink objChain = null; if (_tpOrObject != null && _firstCallDispatched == 0 && Interlocked.CompareExchange(ref _firstCallDispatched, 1, 0) == 0) { // use the instance of server object created to // set up the pipeline. srvObj = (MarshalByRefObject) _tpOrObject; objChain = _serverObjectChain; if (objChain == null) { objChain = _srvCtx.CreateServerObjectChain(srvObj); } } else { // For singleCall we create a fresh object & its chain // on each dispatch! srvObj = (MarshalByRefObject) Activator.CreateInstance((Type)_srvType, true); // make sure that object didn't Marshal itself. // (well known objects should live up to their promise // of exporting themselves through exactly one url) String tempUri = RemotingServices.GetObjectUri(srvObj); if (tempUri != null) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Remoting_WellKnown_CtorCantMarshal"), this.URI)); } // Set the identity depending on whether we have the server // or proxy if(!RemotingServices.IsTransparentProxy(srvObj)) { #if _DEBUG Identity idObj = srvObj.__RaceSetServerIdentity(this); #else srvObj.__RaceSetServerIdentity(this); #endif #if _DEBUG BCLDebug.Assert(idObj == this, "Bad ID state!" ); BCLDebug.Assert(idObj == MarshalByRefObject.GetIdentity(srvObj), "Bad ID state!" ); #endif } else { RealProxy rp = null; rp = RemotingServices.GetRealProxy(srvObj); BCLDebug.Assert(null != rp, "null != rp"); // #if _DEBUG // Identity idObj = (ServerIdentity) rp.SetIdentity(this); // #else rp.IdentityObject = this; // #endif #if false #if _DEBUG // #endif #endif } // Create the object chain and return it objChain = _srvCtx.CreateServerObjectChain(srvObj); } // This is passed out to the caller so that for single-call // case we can call Dispose when the incoming call is done obj = srvObj; return objChain; } } internal Type ServerType { get { return _srvType; } set { _srvType = value; } } // ServerType internal bool MarshaledAsSpecificType { get { return _bMarshaledAsSpecificType; } set { _bMarshaledAsSpecificType = value; } } // MarshaledAsSpecificType internal IMessageSink RaceSetServerObjectChain( IMessageSink serverObjectChain) { if (_serverObjectChain == null) { bool fLocked = false; RuntimeHelpers.PrepareConstrainedRegions(); try { Monitor.ReliableEnter(this, ref fLocked); if (_serverObjectChain == null) { _serverObjectChain = serverObjectChain; } } finally { if (fLocked) { Monitor.Exit(this); } } } return _serverObjectChain; } /*package*/ internal bool AddServerSideDynamicProperty( IDynamicProperty prop) { if (_dphSrv == null) { DynamicPropertyHolder dphSrv = new DynamicPropertyHolder(); bool fLocked = false; RuntimeHelpers.PrepareConstrainedRegions(); try { Monitor.ReliableEnter(this, ref fLocked); if (_dphSrv == null) { _dphSrv = dphSrv; } } finally { if (fLocked) { Monitor.Exit(this); } } } return _dphSrv.AddDynamicProperty(prop); } /*package*/ internal bool RemoveServerSideDynamicProperty(String name) { if (_dphSrv == null) { throw new ArgumentException(Environment.GetResourceString("Arg_PropNotFound") ); } return _dphSrv.RemoveDynamicProperty(name); } internal ArrayWithSize ServerSideDynamicSinks { get { if (_dphSrv == null) { return null; } else { return _dphSrv.DynamicSinks; } } } internal override void AssertValid() { base.AssertValid(); if((null != this.TPOrObject) && !RemotingServices.IsTransparentProxy(this.TPOrObject)) { BCLDebug.Assert(MarshalByRefObject.GetIdentity((MarshalByRefObject)this.TPOrObject) == this, "Server ID mismatch with Object"); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- HttpWebResponse.cs
- DataListComponentEditor.cs
- sqlpipe.cs
- ContainerControl.cs
- CheckBoxBaseAdapter.cs
- ProfileModule.cs
- SimpleHandlerFactory.cs
- Trace.cs
- HwndHost.cs
- WebPartConnectionsConnectVerb.cs
- RequestSecurityToken.cs
- UITypeEditors.cs
- BindableAttribute.cs
- ConstraintEnumerator.cs
- BitmapEffectInput.cs
- BamlLocalizationDictionary.cs
- DataGridViewTextBoxEditingControl.cs
- JavaScriptString.cs
- HostingEnvironmentException.cs
- WinEventWrap.cs
- HttpCacheParams.cs
- TreeNodeMouseHoverEvent.cs
- UrlRoutingModule.cs
- Number.cs
- WindowsPen.cs
- ContextStack.cs
- WebBrowser.cs
- StyleReferenceConverter.cs
- storepermissionattribute.cs
- WebBrowserSiteBase.cs
- DataServiceHost.cs
- MeasurementDCInfo.cs
- DynamicEntity.cs
- JournalNavigationScope.cs
- OptimizerPatterns.cs
- SessionStateContainer.cs
- MaskedTextBoxDesignerActionList.cs
- XmlSchemaSequence.cs
- RemoveStoryboard.cs
- ListViewItemMouseHoverEvent.cs
- ExcludePathInfo.cs
- SettingsAttributes.cs
- PathData.cs
- ParallelTimeline.cs
- DataBindingList.cs
- DesignTimeParseData.cs
- controlskin.cs
- FixedSOMPage.cs
- MdImport.cs
- FormViewPageEventArgs.cs
- BufferedGraphicsManager.cs
- XmlCharCheckingReader.cs
- RelatedImageListAttribute.cs
- SchemaMerger.cs
- TypeDescriptorContext.cs
- AttachedPropertyBrowsableWhenAttributePresentAttribute.cs
- ConstraintCollection.cs
- PeerTransportSecuritySettings.cs
- XPathDocumentNavigator.cs
- DateTimePickerDesigner.cs
- WindowsServiceElement.cs
- InvalidFilterCriteriaException.cs
- SelectionListComponentEditor.cs
- SocketElement.cs
- SerTrace.cs
- XmlReflectionMember.cs
- SchemaAttDef.cs
- ImageListImageEditor.cs
- ByteConverter.cs
- unsafeIndexingFilterStream.cs
- ConfigurationValues.cs
- SizeFConverter.cs
- ApplicationDirectory.cs
- TransactionFlowProperty.cs
- SafeHandle.cs
- LockRecoveryTask.cs
- SaveFileDialog.cs
- PersonalizationState.cs
- ProviderBase.cs
- EntityTypeEmitter.cs
- SqlNotificationEventArgs.cs
- DelegateBodyWriter.cs
- ActivityBindForm.Designer.cs
- MulticastOption.cs
- XmlSchemaSimpleType.cs
- SessionStateContainer.cs
- TCPClient.cs
- WebPartConnectVerb.cs
- ElementHostAutomationPeer.cs
- DataControlFieldCell.cs
- BevelBitmapEffect.cs
- HMACMD5.cs
- StyleBamlRecordReader.cs
- CommaDelimitedStringAttributeCollectionConverter.cs
- ConfigurationLocation.cs
- mediaeventshelper.cs
- WebPartsPersonalization.cs
- RightsManagementInformation.cs
- SqlTrackingQuery.cs
- PauseStoryboard.cs