merging the Mainsoft branch to the trunk
[mono.git] / mcs / class / corlib / System.Runtime.Remoting / ServerIdentity.cs
index 37ee0f7eb0bee322bf0170e669b88bbdbaf3a725..765b8c040787f0f3e7ac6a247fee6226627ceafb 100644 (file)
@@ -6,15 +6,41 @@
 // (C) 2002, Lluis Sanchez Gual
 //
 
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
 using System;
 using System.Runtime.Remoting.Messaging;
 using System.Runtime.Remoting.Contexts;
 using System.Runtime.Remoting.Lifetime;
+using System.Runtime.Remoting.Proxies;
 
 namespace System.Runtime.Remoting
 {
        internal abstract class ServerIdentity : Identity
        {
+               protected Type _objectType;
+
                protected MarshalByRefObject _serverObject;
 
                // Message sink used in the server to dispatch a message
@@ -24,17 +50,22 @@ namespace System.Runtime.Remoting
                protected Context _context;
                protected Lease _lease;
 
-               public ServerIdentity(string objectUri, Context context, Type objectType): base (objectUri, objectType)
+               public ServerIdentity (string objectUri, Context context, Type objectType): base (objectUri)
                {
+                       _objectType = objectType;
                        _context = context;
                }
 
-               public void StartTrackingLifetime ()
+               public Type ObjectType
+               {
+                       get { return _objectType; }
+               }
+
+               public void StartTrackingLifetime (ILease lease)
                {
                        // Adds this identity to the LeaseManager. 
                        // _serverObject must be set.
 
-                       ILease lease = (ILease) _serverObject.InitializeLifetimeService ();
                        if (lease != null && lease.CurrentState == LeaseState.Null) lease = null;
 
                        if (lease != null) 
@@ -63,14 +94,31 @@ namespace System.Runtime.Remoting
                        _objRef = new ObjRef ();
                        _objRef.TypeInfo = new TypeInfo(requestedType);
                        _objRef.URI = _objectUri;
+
+                       if (_envoySink != null && !(_envoySink is EnvoyTerminatorSink))
+                               _objRef.EnvoyInfo = new EnvoyInfo (_envoySink);
+
                        return _objRef;
                }
 
-               public void AttachServerObject (MarshalByRefObject serverObject)
+               public void AttachServerObject (MarshalByRefObject serverObject, Context context)
                {
+                       _context = context;
                        _serverObject = serverObject;
-                       _serverObject.ObjectIdentity = this;
-                       StartTrackingLifetime ();
+                       
+                       if (RemotingServices.IsTransparentProxy (serverObject))
+                       {
+                               RealProxy rp = RemotingServices.GetRealProxy (serverObject);
+                               if (rp.ObjectIdentity == null)
+                                       rp.ObjectIdentity = this;
+                       }
+                       else
+                       {
+                               if (_objectType.IsContextful)
+                                       _envoySink = context.CreateEnvoySink (serverObject);
+       
+                               _serverObject.ObjectIdentity = this;
+                       }
                }
 
                public Lease Lease
@@ -81,6 +129,7 @@ namespace System.Runtime.Remoting
                public Context Context
                {
                        get { return _context; }
+                       set { _context = value; }
                }
 
                public abstract IMessage SyncObjectProcessMessage (IMessage msg);
@@ -88,18 +137,21 @@ namespace System.Runtime.Remoting
 
                protected void DisposeServerObject()
                {
-                       if (_serverObject != null)
-                       {
-                               IDisposable disp = _serverObject as IDisposable;
-                               if (disp != null) disp.Dispose ();
+                       // Detach identity from server object to avoid problems if the
+                       // object is marshalled again.
+                       
+                       if (_serverObject != null) {
+                               _serverObject.ObjectIdentity = null;
+                               _serverObject = null;
                        }
-                       _serverObject = null;
                }
        }
 
        internal class ClientActivatedIdentity : ServerIdentity
        {
-               public ClientActivatedIdentity (string objectUri, Context context, Type objectType): base (objectUri, context, objectType)
+               MarshalByRefObject _targetThis;
+               
+               public ClientActivatedIdentity (string objectUri, Type objectType): base (objectUri, null, objectType)
                {
                }
        
@@ -108,6 +160,16 @@ namespace System.Runtime.Remoting
                        return _serverObject;
                }
 
+               public MarshalByRefObject GetClientProxy ()
+               {
+                       return _targetThis;
+               }
+               
+               public void SetClientProxy (MarshalByRefObject obj)
+               {
+                       _targetThis = obj;
+               }
+
                public override void OnLifetimeExpired()
                {
                        base.OnLifetimeExpired();
@@ -116,13 +178,19 @@ namespace System.Runtime.Remoting
 
                public override IMessage SyncObjectProcessMessage (IMessage msg)
                {
-                       if (_serverSink == null) _serverSink = _context.CreateServerObjectSinkChain (_serverObject);
+                       if (_serverSink == null) {
+                               bool useProxy = _targetThis != null;
+                               _serverSink = _context.CreateServerObjectSinkChain ((useProxy ? _targetThis : _serverObject), useProxy);
+                       }
                        return _serverSink.SyncProcessMessage (msg);
                }
 
                public override IMessageCtrl AsyncObjectProcessMessage (IMessage msg, IMessageSink replySink)
                {
-                       if (_serverSink == null) _serverSink = _context.CreateServerObjectSinkChain (_serverObject);
+                       if (_serverSink == null) {
+                               bool useProxy = _targetThis != null;
+                               _serverSink = _context.CreateServerObjectSinkChain ((useProxy ? _targetThis : _serverObject), useProxy);
+                       }
                        return _serverSink.AsyncProcessMessage (msg, replySink);
                }       
        }
@@ -132,15 +200,18 @@ namespace System.Runtime.Remoting
                public SingletonIdentity (string objectUri, Context context, Type objectType): base (objectUri, context, objectType)
                {
                }
-       
+
                public MarshalByRefObject GetServerObject ()
                {
                        if (_serverObject != null) return _serverObject;
 
                        lock (this) 
                        {
-                               if (_serverObject == null)
-                                       AttachServerObject ((MarshalByRefObject) Activator.CreateInstance (_objectType));
+                               if (_serverObject == null) {
+                                       MarshalByRefObject server = (MarshalByRefObject) Activator.CreateInstance (_objectType, true);
+                                       AttachServerObject (server, Context.DefaultContext);
+                                       StartTrackingLifetime ((ILease)server.InitializeLifetimeService ());
+                               }
                        }
                        return _serverObject;
                }
@@ -148,14 +219,14 @@ namespace System.Runtime.Remoting
                public override IMessage SyncObjectProcessMessage (IMessage msg)
                {
                        MarshalByRefObject obj = GetServerObject ();
-                       if (_serverSink == null) _serverSink = _context.CreateServerObjectSinkChain (obj);
+                       if (_serverSink == null) _serverSink = _context.CreateServerObjectSinkChain (obj, false);
                        return _serverSink.SyncProcessMessage (msg);
                }
 
                public override IMessageCtrl AsyncObjectProcessMessage (IMessage msg, IMessageSink replySink)
                {
                        MarshalByRefObject obj = GetServerObject ();
-                       if (_serverSink == null) _serverSink = _context.CreateServerObjectSinkChain (obj);
+                       if (_serverSink == null) _serverSink = _context.CreateServerObjectSinkChain (obj, false);
                        return _serverSink.AsyncProcessMessage (msg, replySink);
                }       
        }
@@ -170,9 +241,9 @@ namespace System.Runtime.Remoting
                {
                        // SingleCallIdentity creates and disposes an instance in each call
 
-                       MarshalByRefObject obj = (MarshalByRefObject)Activator.CreateInstance (_objectType);
-                       obj.ObjectIdentity = this;
-                       IMessageSink serverSink = _context.CreateServerObjectSinkChain(obj);
+                       MarshalByRefObject obj = (MarshalByRefObject)Activator.CreateInstance (_objectType, true);
+                       if (obj.ObjectIdentity == null) obj.ObjectIdentity = this;
+                       IMessageSink serverSink = _context.CreateServerObjectSinkChain (obj, false);
                        IMessage result = serverSink.SyncProcessMessage (msg);
                        if (obj is IDisposable) ((IDisposable)obj).Dispose();
                        return result;
@@ -180,8 +251,8 @@ namespace System.Runtime.Remoting
 
                public override IMessageCtrl AsyncObjectProcessMessage (IMessage msg, IMessageSink replySink)
                {
-                       MarshalByRefObject obj = (MarshalByRefObject)Activator.CreateInstance (_objectType);
-                       IMessageSink serverSink = _context.CreateServerObjectSinkChain(obj);
+                       MarshalByRefObject obj = (MarshalByRefObject)Activator.CreateInstance (_objectType, true);
+                       IMessageSink serverSink = _context.CreateServerObjectSinkChain (obj, false);
                        if (obj is IDisposable) replySink = new DisposerReplySink(replySink, ((IDisposable)obj));
                        return serverSink.AsyncProcessMessage (msg, replySink);
                }