StackBuilderSink.cs: Implemented AsyncProcessMessage().
[mono.git] / mcs / class / corlib / System.Runtime.Remoting.Messaging / StackBuilderSink.cs
1 //
2 // System.Runtime.Remoting.StackBuilderSink.cs
3 //
4 // Author: Lluis Sanchez Gual (lsg@ctv.es)
5 //
6 // (C) 2002, Lluis Sanchez Gual
7 //
8
9 using System;
10 using System.Threading;
11 using System.Reflection;
12
13 namespace System.Runtime.Remoting.Messaging
14 {
15         // Sink that calls the real method of the object
16
17         public class StackBuilderSink: IMessageSink
18         {
19                 MarshalByRefObject _target;
20
21                 public StackBuilderSink (MarshalByRefObject obj)
22                 {
23                         _target = obj;
24                 }
25
26                 public IMessage SyncProcessMessage (IMessage msg)
27                 {
28                         CheckParameters (msg);
29
30                         // Makes the real call to the object
31                         return RemotingServices.InternalExecuteMessage (_target, (IMethodCallMessage)msg);
32                 }
33
34                 public IMessageCtrl AsyncProcessMessage (IMessage msg, IMessageSink replySink)
35                 {
36                         object[] parms = new object[] {msg, replySink};
37                         ThreadPool.QueueUserWorkItem (new WaitCallback (ExecuteAsyncMessage), parms);
38                         return null;
39                 }
40                 
41                 void ExecuteAsyncMessage (object ob)
42                 {
43                         object[] parms = (object[]) ob;
44                         IMethodCallMessage msg = (IMethodCallMessage) parms[0];
45                         IMessageSink replySink = (IMessageSink)parms[1];
46                         
47                         CheckParameters (msg);
48                         IMessage res = RemotingServices.InternalExecuteMessage (_target, msg);
49                         
50                         replySink.SyncProcessMessage (res);
51                 }
52
53                 public IMessageSink NextSink 
54                 { 
55                         get { return null; }
56                 }
57
58                 void CheckParameters (IMessage msg)
59                 {
60                         IMethodCallMessage mcm = (IMethodCallMessage) msg;
61                         
62                         MethodInfo mi = (MethodInfo) mcm.MethodBase;
63
64                         ParameterInfo[] parameters = mi.GetParameters();
65                         int narg = 0;
66
67                         foreach (ParameterInfo pi in parameters)
68                         {
69                                 object pval = mcm.GetArg (narg++);
70                                 Type pt = pi.ParameterType;
71                                 if (pt.IsByRef) pt = pt.GetElementType ();
72                                 
73                                 if (pval != null && !pt.IsInstanceOfType (pval))
74                                         throw new RemotingException ("Cannot cast argument " + pi.Position + " of type '" + pval.GetType().AssemblyQualifiedName +
75                                                 "' to type '" + pt.AssemblyQualifiedName + "'");
76                         }
77                 }
78         }
79 }