예제 #1
0
        bool DispatchAndReleasePump(RequestContext request, bool cleanThread, OperationContext currentOperationContext)
        {
            ServiceChannel channel = this.requestInfo.Channel;
            EndpointDispatcher endpoint = this.requestInfo.Endpoint;
            bool releasedPump = false;

            try
            {
                DispatchRuntime dispatchBehavior = this.requestInfo.DispatchRuntime;

                if (channel == null || dispatchBehavior == null)
                {
                    Fx.Assert("System.ServiceModel.Dispatcher.ChannelHandler.Dispatch(): (channel == null || dispatchBehavior == null)");
                    return true;
                }

                MessageBuffer buffer = null;
                Message message;

                EventTraceActivity eventTraceActivity = TraceDispatchMessageStart(request.RequestMessage);
                AspNetEnvironment.Current.PrepareMessageForDispatch(request.RequestMessage);
                if (dispatchBehavior.PreserveMessage)
                {
                    object previousBuffer = null;
                    if (request.RequestMessage.Properties.TryGetValue(MessageBufferPropertyName, out previousBuffer))
                    {
                        buffer = (MessageBuffer)previousBuffer;
                        message = buffer.CreateMessage();
                    }
                    else
                    {
                        // 
                        buffer = request.RequestMessage.CreateBufferedCopy(int.MaxValue);
                        message = buffer.CreateMessage();
                    }
                }
                else
                {
                    message = request.RequestMessage;
                }

                DispatchOperationRuntime operation = dispatchBehavior.GetOperation(ref message);
                if (operation == null)
                {
                    Fx.Assert("ChannelHandler.Dispatch (operation == null)");
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "No DispatchOperationRuntime found to process message.")));
                }

                if (this.shouldRejectMessageWithOnOpenActionHeader && message.Headers.Action == OperationDescription.SessionOpenedAction)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxNoEndpointMatchingAddressForConnectionOpeningMessage, message.Headers.Action, "Open")));
                }

                if (MessageLogger.LoggingEnabled)
                {
                    MessageLogger.LogMessage(ref message, (operation.IsOneWay ? MessageLoggingSource.ServiceLevelReceiveDatagram : MessageLoggingSource.ServiceLevelReceiveRequest) | MessageLoggingSource.LastChance);
                }

                if (operation.IsTerminating && this.hasSession)
                {
                    this.isChannelTerminated = true;
                }

                bool hasOperationContextBeenSet;
                if (currentOperationContext != null)
                {
                    hasOperationContextBeenSet = true;
                    currentOperationContext.ReInit(request, message, channel);
                }
                else
                {
                    hasOperationContextBeenSet = false;
                    currentOperationContext = new OperationContext(request, message, channel, this.host);
                }

                if (dispatchBehavior.PreserveMessage)
                {
                    currentOperationContext.IncomingMessageProperties.Add(MessageBufferPropertyName, buffer);
                }

                if (currentOperationContext.EndpointDispatcher == null && this.listener != null)
                {
                    currentOperationContext.EndpointDispatcher = endpoint;
                }

                MessageRpc rpc = new MessageRpc(request, message, operation, channel, this.host,
                    this, cleanThread, currentOperationContext, this.requestInfo.ExistingInstanceContext, eventTraceActivity);

                TraceUtility.MessageFlowAtMessageReceived(message, currentOperationContext, eventTraceActivity, true);

                rpc.TransactedBatchContext = this.transactedBatchContext;

                // passing responsibility for call throttle to MessageRpc
                // (MessageRpc implicitly owns this throttle once it's created)
                this.requestInfo.ChannelHandlerOwnsCallThrottle = false;
                // explicitly passing responsibility for instance throttle to MessageRpc
                rpc.MessageRpcOwnsInstanceContextThrottle = this.requestInfo.ChannelHandlerOwnsInstanceContextThrottle;
                this.requestInfo.ChannelHandlerOwnsInstanceContextThrottle = false;

                // These need to happen before Dispatch but after accessing any ChannelHandler
                // state, because we go multi-threaded after this until we reacquire pump mutex.
                this.ReleasePump();
                releasedPump = true;

                return operation.Parent.Dispatch(ref rpc, hasOperationContextBeenSet);
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }
                return this.HandleError(e, request, channel);
            }
            finally
            {
                if (!releasedPump)
                {
                    this.ReleasePump();
                }
            }
        }
 private bool DispatchAndReleasePump(RequestContext request, bool cleanThread, OperationContext currentOperationContext)
 {
     bool flag3;
     ServiceChannel channel = this.requestInfo.Channel;
     EndpointDispatcher endpoint = this.requestInfo.Endpoint;
     bool flag = false;
     try
     {
         Message requestMessage;
         bool flag2;
         DispatchRuntime dispatchRuntime = this.requestInfo.DispatchRuntime;
         if ((channel == null) || (dispatchRuntime == null))
         {
             return true;
         }
         MessageBuffer property = null;
         if (dispatchRuntime.PreserveMessage)
         {
             object obj2 = null;
             if (request.RequestMessage.Properties.TryGetValue("_RequestMessageBuffer_", out obj2))
             {
                 property = (MessageBuffer) obj2;
                 requestMessage = property.CreateMessage();
             }
             else
             {
                 property = request.RequestMessage.CreateBufferedCopy(0x7fffffff);
                 requestMessage = property.CreateMessage();
             }
         }
         else
         {
             requestMessage = request.RequestMessage;
         }
         DispatchOperationRuntime operation = dispatchRuntime.GetOperation(ref requestMessage);
         if (operation == null)
         {
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "No DispatchOperationRuntime found to process message.", new object[0])));
         }
         if (MessageLogger.LoggingEnabled)
         {
             MessageLogger.LogMessage(ref requestMessage, (operation.IsOneWay ? MessageLoggingSource.ServiceLevelReceiveDatagram : MessageLoggingSource.ServiceLevelReceiveRequest) | MessageLoggingSource.LastChance);
         }
         if (operation.IsTerminating && this.hasSession)
         {
             this.isChannelTerminated = true;
         }
         if (currentOperationContext != null)
         {
             flag2 = true;
             currentOperationContext.ReInit(request, requestMessage, channel);
         }
         else
         {
             flag2 = false;
             currentOperationContext = new OperationContext(request, requestMessage, channel, this.host);
         }
         if (dispatchRuntime.PreserveMessage)
         {
             currentOperationContext.IncomingMessageProperties.Add("_RequestMessageBuffer_", property);
         }
         if ((currentOperationContext.EndpointDispatcher == null) && (this.listener != null))
         {
             currentOperationContext.EndpointDispatcher = endpoint;
         }
         MessageRpc rpc = new MessageRpc(request, requestMessage, operation, channel, this.host, this, cleanThread, currentOperationContext, this.requestInfo.ExistingInstanceContext);
         TraceUtility.MessageFlowAtMessageReceived(requestMessage, currentOperationContext, true);
         rpc.TransactedBatchContext = this.transactedBatchContext;
         this.requestInfo.ChannelHandlerOwnsCallThrottle = false;
         rpc.MessageRpcOwnsInstanceContextThrottle = this.requestInfo.ChannelHandlerOwnsInstanceContextThrottle;
         this.requestInfo.ChannelHandlerOwnsInstanceContextThrottle = false;
         this.ReleasePump();
         flag = true;
         flag3 = operation.Parent.Dispatch(ref rpc, flag2);
     }
     catch (Exception exception)
     {
         if (Fx.IsFatal(exception))
         {
             throw;
         }
         flag3 = this.HandleError(exception, request, channel);
     }
     finally
     {
         if (!flag)
         {
             this.ReleasePump();
         }
     }
     return flag3;
 }