// 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;\r
using System.Threading;\r
public virtual IMessageSink CreateMessageSink(String url, Object data, out String uri) \r
{\r
uri = null;\r
- IMessageSink sink = null;\r
\r
- if (url == null && data != null) \r
+ if (data != null) \r
{\r
// Get the data and then get the sink\r
CrossAppDomainData cadData = data as CrossAppDomainData;\r
if (cadData != null && cadData.ProcessID == RemotingConfiguration.ProcessId)\r
// GetSink creates a new sink if we don't have any (use contexts here later)\r
- sink = CrossAppDomainSink.GetSink(cadData.DomainID);\r
+ return CrossAppDomainSink.GetSink(cadData.DomainID);\r
} \r
- else \r
- {\r
- if (url != null && data == null) \r
- {\r
- if (url.StartsWith(_strName)) \r
- {\r
- throw new NotSupportedException("Can't create a named channel via crossappdomain");\r
- }\r
- }\r
- }\r
+ if (url != null && url.StartsWith(_strName)) \r
+ throw new NotSupportedException("Can't create a named channel via crossappdomain");\r
\r
- return sink;\r
+ return null;\r
}
}
\r
internal class CrossAppDomainSink : IMessageSink \r
{\r
private static Hashtable s_sinks = new Hashtable();\r
+
+ private static MethodInfo processMessageMethod =
+ typeof (CrossAppDomainSink).GetMethod ("ProcessMessageInDomain", BindingFlags.NonPublic|BindingFlags.Static);
+
\r
private int _domainID;\r
\r
return sink;\r
}\r
}\r
+ }\r
+ \r
+ internal int TargetDomainId {\r
+ get { return _domainID; }\r
+ }
+
+ private struct ProcessMessageRes {
+ public byte[] arrResponse;
+ public CADMethodReturnMessage cadMrm;
+ }
+
+ 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(); \r
+ }
+ return res;
}
\r
public virtual IMessage SyncProcessMessage(IMessage msgRequest) \r
\r
object threadStatus = Thread.ResetDataStoreStatus ();\r
Context currentContext = Thread.CurrentContext;
- AppDomain currentDomain = AppDomain.InternalSetDomainByID ( _domainID );\r
- try
- {
- AppDomain.CurrentDomain.ProcessMessageInDomain (arrRequest, cadMsg, out arrResponse, out cadMrm);
+ 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;
}
- catch (Exception e)
- {
- IMessage errorMsg = new MethodResponse (e, new ErrorMessage());
- arrResponse = CADSerializer.SerializeMessage (errorMsg).GetBuffer(); \r
- }
- finally
- {
- AppDomain.InternalSetDomain (currentDomain);
+ finally {
AppDomain.InternalSetContext (currentContext);
- Thread.RestoreDataStoreStatus (threadStatus);\r
- }\r
+ Thread.RestoreDataStoreStatus (threadStatus);
+ }
+
\r
if (null != arrResponse) {\r
// Time to deserialize the message\r
{\r
try\r
{\r
- Console.WriteLine("Exception in base domain");
retMessage = new ReturnMessage (e, msgRequest as IMethodCallMessage);
}\r
catch (Exception)\r
return retMessage;\r
}
- public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink) \r
+ public virtual IMessageCtrl AsyncProcessMessage (IMessage reqMsg, IMessageSink replySink) \r
{\r
- throw new NotSupportedException();\r
+ AsyncRequest req = new AsyncRequest (reqMsg, replySink);\r
+ ThreadPool.QueueUserWorkItem (new WaitCallback (SendAsyncMessage), req);\r
+ return null;\r
}
\r
+ public void SendAsyncMessage (object data)\r
+ {\r
+ AsyncRequest req = (AsyncRequest)data;\r
+ IMessage response = SyncProcessMessage (req.MsgRequest);\r
+ req.ReplySink.SyncProcessMessage (response);\r
+ }\r
+ \r
public IMessageSink NextSink { get { return null; } }\r
}
\r
return serializer.Deserialize (mem);\r
}
+ }\r
+ \r
+ internal class AsyncRequest\r
+ {\r
+ internal IMessageSink ReplySink;\r
+ internal IMessage MsgRequest;\r
+ \r
+ public AsyncRequest (IMessage msgRequest, IMessageSink replySink)\r
+ {\r
+ ReplySink = replySink;\r
+ MsgRequest = msgRequest;\r
+ }\r
}
}