Merge pull request #82 from Unity-Technologies/master-gc-race
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Dispatcher / InputOrReplyRequestProcessor.cs
1 using System;
2 using System.Collections.Generic;
3 using System.ServiceModel;
4 using System.ServiceModel.Channels;
5 using System.ServiceModel.Security;
6 using System.ServiceModel.Security.Tokens;
7 using System.Text;
8 using System.ServiceModel.MonoInternal;
9
10 namespace System.ServiceModel.Dispatcher
11 {
12         // Its lifetime is per-call.
13         // ServiceRuntimeChannel's lifetime is per-session.
14         internal class InputOrReplyRequestProcessor : BaseRequestProcessor
15         {
16                 DispatchRuntime dispatch_runtime;
17                 IChannel reply_or_input;
18                 IContextChannel context_channel;
19
20                 public InputOrReplyRequestProcessor (DispatchRuntime runtime, IChannel replyOrInput)
21                 {
22                         Init (runtime, replyOrInput);
23
24                         //initialization
25                         InitializeChain.AddHandler (new InitializingHandler ());
26
27                         //processing
28                         ProcessingChain.AddHandler (new PostReceiveRequestHandler ()).
29                                                         AddHandler (new OperationInvokerHandler (replyOrInput));
30
31                         //errors
32                         ErrorChain.AddHandler (new ErrorProcessingHandler (replyOrInput));
33
34                         //finalize
35                         FinalizationChain.AddHandler (new FinalizeProcessingHandler ());
36                 }
37
38                 void Init (DispatchRuntime runtime, IChannel replyOrInput)
39                 {
40                         dispatch_runtime = runtime;
41                         reply_or_input = replyOrInput;
42                 }
43
44                 public void ProcessInput (Message message)
45                 {
46                         OperationContext opcx = CreateOperationContext (message);
47                         ProcessRequest (new MessageProcessingContext (opcx, reply_or_input));
48                 }
49
50                 public void ProcessReply (RequestContext rc)
51                 {
52                         OperationContext opcx = CreateOperationContext (rc.RequestMessage);
53                         opcx.RequestContext = rc;
54                         ProcessRequest (new MessageProcessingContext (opcx, reply_or_input));
55                 }
56
57                 OperationContext CreateOperationContext (Message incoming)
58                 {
59                         IContextChannel contextChannel;
60                         if (dispatch_runtime.CallbackClientRuntime.CallbackClientType != null) {
61 #if DISABLE_REAL_PROXY
62                                 var type = ServiceProxyGenerator.CreateCallbackProxyType (dispatch_runtime, dispatch_runtime.CallbackClientRuntime.CallbackClientType);
63                                 contextChannel = (ServiceRuntimeChannel) Activator.CreateInstance (type, new object [] {reply_or_input, dispatch_runtime});
64 #else
65                                 contextChannel = (IContextChannel) new ClientRealProxy (dispatch_runtime.CallbackClientRuntime.CallbackClientType, new DuplexServiceRuntimeChannel (reply_or_input, dispatch_runtime), true).GetTransparentProxy ();
66 #endif
67                         }
68                         else
69                                 contextChannel = new ServiceRuntimeChannel (reply_or_input, dispatch_runtime);
70                         contextChannel.Open (); // FIXME: timeout?
71                         OperationContext opCtx = new OperationContext (contextChannel);
72                         opCtx.IncomingMessage = incoming;
73                         opCtx.EndpointDispatcher = dispatch_runtime.EndpointDispatcher;
74                         context_channel = contextChannel;
75                         return opCtx;
76                 }
77         }
78 }