CrossAppDomainChannel.cs :  » 2.6.4-mono-.net-core » System.Runtime » System » Runtime » Remoting » Channels » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » 2.6.4 mono .net core » System.Runtime 
System.Runtime » System » Runtime » Remoting » Channels » CrossAppDomainChannel.cs
//
// System.Runtime.Remoting.Channels.CrossAppDomainChannel.cs
//
// Author: Patrik Torstensson (totte_mono@yahoo.com)
//         Lluis Sanchez Gual (lluis@ximian.com)
//
// 2003 (C) Copyright, Ximian, Inc.
//

//
// 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.Collections;
using System.IO;
using System.Threading;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;   
using System.Runtime.Remoting.Channels; 
using System.Runtime.Remoting.Contexts; 
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Reflection;

namespace System.Runtime.Remoting.Channels{

  // Holds the cross appdomain channel data (used to get/create the correct sink)
  [Serializable]
  internal class CrossAppDomainData 
  {
    // TODO: Add context support
    // Required for .NET compatibility
#pragma warning disable 0414
    private object _ContextID;
#pragma warning restore
    private int _DomainID;
    private string _processGuid;

    internal CrossAppDomainData(int domainId) 
    {
      _ContextID = (int) 0;
      _DomainID = domainId;
      _processGuid = RemotingConfiguration.ProcessId;
    }

    internal int DomainID 
    {  
      get { return _DomainID;  }
    }

    internal string ProcessID
    {
      get { return _processGuid; }
    }
  }

  // Responsible for marshalling objects between appdomains
  [Serializable]
  internal class CrossAppDomainChannel : IChannel, IChannelSender, IChannelReceiver 
  {
    private const String _strName = "MONOCAD";
    
    private static Object s_lock = new Object();

    internal static void RegisterCrossAppDomainChannel() 
    {
      lock (s_lock) 
      {
        // todo: make singleton
        CrossAppDomainChannel monocad = new CrossAppDomainChannel();
        ChannelServices.RegisterChannel ((IChannel) monocad);
      }
    }    

    // IChannel implementation
    public virtual String ChannelName 
    {
      get { return _strName; }
    }
    
    public virtual int ChannelPriority 
    {
      get { return 100; }
    }
    
    public String Parse(String url, out String objectURI) 
    {
      objectURI = url;
      return null;
    }  

    // IChannelReceiver
    public virtual Object ChannelData 
    {
      get { return new CrossAppDomainData(Thread.GetDomainID()); }
    }  
    
    public virtual String[] GetUrlsForUri(String objectURI) 
    {
      throw new NotSupportedException("CrossAppdomain channel dont support UrlsForUri");
    }  
    
    // Dummies
    public virtual void StartListening(Object data) {}
    public virtual void StopListening(Object data) {}  

    // IChannelSender
    public virtual IMessageSink CreateMessageSink(String url, Object data, out String uri) 
    {
      uri = null;
            
      if (data != null) 
      {
        // Get the data and then get the sink
        CrossAppDomainData cadData = data as CrossAppDomainData;
        if (cadData != null && cadData.ProcessID == RemotingConfiguration.ProcessId)
          // GetSink creates a new sink if we don't have any (use contexts here later)
          return CrossAppDomainSink.GetSink(cadData.DomainID);
      } 
      if (url != null && url.StartsWith(_strName)) 
        throw new NotSupportedException("Can't create a named channel via crossappdomain");

      return null;
    }
  }
  
  [MonoTODO("Handle domain unloading?")]
  internal class CrossAppDomainSink : IMessageSink 
  {
    private static Hashtable s_sinks = new Hashtable();

    private static MethodInfo processMessageMethod =
      typeof (CrossAppDomainSink).GetMethod ("ProcessMessageInDomain", BindingFlags.NonPublic|BindingFlags.Static);


    private int _domainID;

    internal CrossAppDomainSink(int domainID) 
    {
      _domainID = domainID;
    }
    
    internal static CrossAppDomainSink GetSink(int domainID) 
    {
      // Check if we have a sink for the current domainID
      // note, locking is not to bad here, very few class to GetSink
      lock (s_sinks.SyncRoot) 
      {
        if (s_sinks.ContainsKey(domainID)) 
          return (CrossAppDomainSink) s_sinks[domainID];
        else 
        {
          CrossAppDomainSink sink = new CrossAppDomainSink(domainID);
          s_sinks[domainID] = sink;

          return sink;
        }
      }
    }
    
    internal int TargetDomainId {
      get { return _domainID; }
    }

    private struct ProcessMessageRes {
      public byte[] arrResponse;
      public CADMethodReturnMessage cadMrm;
    }

#pragma warning disable 169
    private static ProcessMessageRes ProcessMessageInDomain (
      byte[] arrRequest,
      CADMethodCallMessage cadMsg)
      {
      ProcessMessageRes res = new ProcessMessageRes ();

      try 
      {
        AppDomain.CurrentDomain.ProcessMessageInDomain (arrRequest, cadMsg, out res.arrResponse, out res.cadMrm);
      }
      catch (Exception e) 
      {
        IMessage errorMsg = new MethodResponse (e, new ErrorMessage());
        res.arrResponse = CADSerializer.SerializeMessage (errorMsg).GetBuffer(); 
      }
      return res;
    }
#pragma warning restore 169

    public virtual IMessage SyncProcessMessage(IMessage msgRequest) 
    {
      IMessage retMessage = null;

      try 
      {
        // Time to transit into the "our" domain
        byte [] arrResponse = null;
        byte [] arrRequest = null; 
        
        CADMethodReturnMessage cadMrm = null;
        CADMethodCallMessage cadMsg;
        
        cadMsg = CADMethodCallMessage.Create (msgRequest);
        if (null == cadMsg) {
          // Serialize the request message
          MemoryStream reqMsgStream = CADSerializer.SerializeMessage(msgRequest);
          arrRequest = reqMsgStream.GetBuffer();
        }

        Context currentContext = Thread.CurrentContext;

        try {
          // InternalInvoke can't handle out arguments, this is why
          // we return the results in a structure
          ProcessMessageRes res = (ProcessMessageRes)AppDomain.InvokeInDomainByID (_domainID, processMessageMethod, null, new object [] { arrRequest, cadMsg });
          arrResponse = res.arrResponse;
          cadMrm = res.cadMrm;
        } finally {
          AppDomain.InternalSetContext (currentContext);
        }          

        
        if (null != arrResponse) {
          // Time to deserialize the message
          MemoryStream respMsgStream = new MemoryStream(arrResponse);

          // Deserialize the response message
          retMessage = CADSerializer.DeserializeMessage(respMsgStream, msgRequest as IMethodCallMessage);
        } else
          retMessage = new MethodResponse (msgRequest as IMethodCallMessage, cadMrm);
      }
      catch (Exception e) 
      {
        try
        {
          retMessage = new ReturnMessage (e, msgRequest as IMethodCallMessage);
        }
        catch (Exception)
        {
          // this is just to be sure
        }
      }

        return retMessage;
    }

    public virtual IMessageCtrl AsyncProcessMessage (IMessage reqMsg, IMessageSink replySink) 
    {
      AsyncRequest req = new AsyncRequest (reqMsg, replySink);
      ThreadPool.QueueUserWorkItem (new WaitCallback (SendAsyncMessage), req);
      return null;
    }
    
    public void SendAsyncMessage (object data)
    {
      AsyncRequest req = (AsyncRequest)data;
      IMessage response = SyncProcessMessage (req.MsgRequest);
      req.ReplySink.SyncProcessMessage (response);
    }
    
    public IMessageSink NextSink { get { return null; } }
  }

  internal class CADSerializer 
  {
    internal static IMessage DeserializeMessage(MemoryStream mem, IMethodCallMessage msg)
    {
      BinaryFormatter serializer = new BinaryFormatter();                

      serializer.SurrogateSelector = null;
      mem.Position = 0;

      if (msg == null)
        return (IMessage) serializer.Deserialize(mem, null);
      else
        return (IMessage) serializer.DeserializeMethodResponse(mem, null, msg);
    }
    
    internal static MemoryStream SerializeMessage(IMessage msg)
    {
      MemoryStream mem = new MemoryStream ();
      BinaryFormatter serializer = new BinaryFormatter ();                

      serializer.SurrogateSelector = new RemotingSurrogateSelector ();
      serializer.Serialize (mem, msg);

      mem.Position = 0;

      return mem;
    }

    internal static MemoryStream SerializeObject(object obj)
    {
      MemoryStream mem = new MemoryStream ();
      BinaryFormatter serializer = new BinaryFormatter ();                

      serializer.SurrogateSelector = new RemotingSurrogateSelector ();
      serializer.Serialize (mem, obj);

      mem.Position = 0;

      return mem;
    }

    internal static object DeserializeObject(MemoryStream mem)
    {
      BinaryFormatter serializer = new BinaryFormatter();                

      serializer.SurrogateSelector = null;
      mem.Position = 0;

      return serializer.Deserialize (mem);
    }
  }
  
  internal class AsyncRequest
  {
    internal IMessageSink ReplySink;
    internal IMessage MsgRequest;
    
    public AsyncRequest (IMessage msgRequest, IMessageSink replySink)
    {
      ReplySink = replySink;
      MsgRequest = msgRequest;
    }
  }

}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.