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; }