Imported Upstream version 4.0.0~alpha1

Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
Jo Shields
2015-04-07 09:35:12 +01:00
parent 283343f570
commit 3c1f479b9d
22469 changed files with 2931443 additions and 869343 deletions

View File

@@ -0,0 +1,118 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System;
using System.ServiceModel.Channels;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Runtime.Serialization;
[DataContract]
public class ActionMessageFilter : MessageFilter
{
Dictionary<string, int> actions;
ReadOnlyCollection<string> actionSet;
[DataMember(IsRequired = true)]
internal string[] DCActions
{
get
{
string[] act = new string[this.actions.Count];
actions.Keys.CopyTo(act, 0);
return act;
}
set
{
Init(value);
}
}
public ActionMessageFilter(params string[] actions)
{
if (actions == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("actions");
}
Init(actions);
}
void Init(string[] actions)
{
if (actions.Length == 0)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ActionFilterEmptyList), "actions"));
}
this.actions = new Dictionary<string, int>();
for (int i = 0; i < actions.Length; ++i)
{
// Duplicates are removed
if (!this.actions.ContainsKey(actions[i]))
{
this.actions.Add(actions[i], 0);
}
}
}
public ReadOnlyCollection<string> Actions
{
get
{
if (this.actionSet == null)
{
this.actionSet = new ReadOnlyCollection<string>(new List<string>(this.actions.Keys));
}
return this.actionSet;
}
}
protected internal override IMessageFilterTable<FilterData> CreateFilterTable<FilterData>()
{
return new ActionMessageFilterTable<FilterData>();
}
bool InnerMatch(Message message)
{
string act = message.Headers.Action;
if (act == null)
{
act = string.Empty;
}
return this.actions.ContainsKey(act);
}
public override bool Match(Message message)
{
if (message == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
}
return InnerMatch(message);
}
public override bool Match(MessageBuffer messageBuffer)
{
if (messageBuffer == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageBuffer");
}
Message msg = messageBuffer.CreateMessage();
try
{
return InnerMatch(msg);
}
finally
{
msg.Close();
}
}
}
}

View File

@@ -0,0 +1,84 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.ServiceModel.Channels;
class AndMessageFilter : MessageFilter
{
MessageFilter filter1;
MessageFilter filter2;
public AndMessageFilter(MessageFilter filter1, MessageFilter filter2)
{
if (filter1 == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter1");
if (filter2 == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter2");
this.filter1 = filter1;
this.filter2 = filter2;
}
public MessageFilter Filter1
{
get
{
return this.filter1;
}
}
public MessageFilter Filter2
{
get
{
return this.filter2;
}
}
protected internal override IMessageFilterTable<FilterData> CreateFilterTable<FilterData>()
{
return new AndMessageFilterTable<FilterData>();
}
public override bool Match(Message message)
{
if (message == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
}
return this.filter1.Match(message) && this.filter2.Match(message);
}
internal bool Match(Message message, out bool addressMatched)
{
if (message == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
}
if (this.filter1.Match(message))
{
addressMatched = true;
return this.filter2.Match(message);
}
else
{
addressMatched = false;
return false;
}
}
public override bool Match(MessageBuffer messageBuffer)
{
if (messageBuffer == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageBuffer");
}
return this.filter1.Match(messageBuffer) && this.filter2.Match(messageBuffer);
}
}
}

View File

@@ -0,0 +1,483 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Diagnostics;
class AndMessageFilterTable<FilterData> : IMessageFilterTable<FilterData>
{
Dictionary<MessageFilter, FilterData> filters;
Dictionary<MessageFilter, FilterDataPair> filterData;
MessageFilterTable<FilterDataPair> table;
public AndMessageFilterTable()
{
this.filters = new Dictionary<MessageFilter, FilterData>();
this.filterData = new Dictionary<MessageFilter, FilterDataPair>();
this.table = new MessageFilterTable<FilterDataPair>();
}
public FilterData this[MessageFilter filter]
{
get
{
return this.filters[filter];
}
set
{
if (this.filters.ContainsKey(filter))
{
this.filters[filter] = value;
this.filterData[filter].data = value;
}
else
{
Add(filter, value);
}
}
}
public int Count
{
get
{
return this.filters.Count;
}
}
public bool IsReadOnly
{
get
{
return false;
}
}
public ICollection<MessageFilter> Keys
{
get
{
return this.filters.Keys;
}
}
public ICollection<FilterData> Values
{
get
{
return this.filters.Values;
}
}
public void Add(MessageFilter filter, FilterData data)
{
if (filter == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter");
}
this.Add((AndMessageFilter)filter, data);
}
public void Add(KeyValuePair<MessageFilter, FilterData> item)
{
this.Add(item.Key, item.Value);
}
public void Add(AndMessageFilter filter, FilterData data)
{
if (filter == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter");
}
this.filters.Add(filter, data);
FilterDataPair pair = new FilterDataPair(filter, data);
this.filterData.Add(filter, pair);
this.table.Add(filter.Filter1, pair);
}
public void Clear()
{
this.filters.Clear();
this.filterData.Clear();
this.table.Clear();
}
public bool Contains(KeyValuePair<MessageFilter, FilterData> item)
{
return ((ICollection<KeyValuePair<MessageFilter, FilterData>>)this.filters).Contains(item);
}
public bool ContainsKey(MessageFilter filter)
{
if (filter == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter");
}
return this.filters.ContainsKey(filter);
}
public void CopyTo(KeyValuePair<MessageFilter, FilterData>[] array, int arrayIndex)
{
((ICollection<KeyValuePair<MessageFilter, FilterData>>)this.filters).CopyTo(array, arrayIndex);
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public IEnumerator<KeyValuePair<MessageFilter, FilterData>> GetEnumerator()
{
return this.filters.GetEnumerator();
}
FilterDataPair InnerMatch(Message message)
{
List<FilterDataPair> pairs = new List<FilterDataPair>();
this.table.GetMatchingValues(message, pairs);
FilterDataPair pair = null;
for (int i = 0; i < pairs.Count; ++i)
{
if (pairs[i].filter.Filter2.Match(message))
{
if (pair != null)
{
Collection<MessageFilter> matches = new Collection<MessageFilter>();
matches.Add(pair.filter);
matches.Add(pairs[i].filter);
throw TraceUtility.ThrowHelperError(new MultipleFilterMatchesException(SR.GetString(SR.FilterMultipleMatches), null, matches), message);
}
pair = pairs[i];
}
}
return pair;
}
FilterDataPair InnerMatch(MessageBuffer messageBuffer)
{
List<FilterDataPair> pairs = new List<FilterDataPair>();
this.table.GetMatchingValues(messageBuffer, pairs);
FilterDataPair pair = null;
for (int i = 0; i < pairs.Count; ++i)
{
if (pairs[i].filter.Filter2.Match(messageBuffer))
{
if (pair != null)
{
Collection<MessageFilter> matches = new Collection<MessageFilter>();
matches.Add(pair.filter);
matches.Add(pairs[i].filter);
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MultipleFilterMatchesException(SR.GetString(SR.FilterMultipleMatches), null, matches));
}
pair = pairs[i];
}
}
return pair;
}
void InnerMatch(Message message, ICollection<MessageFilter> results)
{
List<FilterDataPair> pairs = new List<FilterDataPair>();
this.table.GetMatchingValues(message, pairs);
for (int i = 0; i < pairs.Count; ++i)
{
if (pairs[i].filter.Filter2.Match(message))
{
results.Add(pairs[i].filter);
}
}
}
void InnerMatchData(Message message, ICollection<FilterData> results)
{
List<FilterDataPair> pairs = new List<FilterDataPair>();
this.table.GetMatchingValues(message, pairs);
for (int i = 0; i < pairs.Count; ++i)
{
if (pairs[i].filter.Filter2.Match(message))
{
results.Add(pairs[i].data);
}
}
}
void InnerMatch(MessageBuffer messageBuffer, ICollection<MessageFilter> results)
{
List<FilterDataPair> pairs = new List<FilterDataPair>();
this.table.GetMatchingValues(messageBuffer, pairs);
for (int i = 0; i < pairs.Count; ++i)
{
if (pairs[i].filter.Filter2.Match(messageBuffer))
{
results.Add(pairs[i].filter);
}
}
}
void InnerMatchData(MessageBuffer messageBuffer, ICollection<FilterData> results)
{
List<FilterDataPair> pairs = new List<FilterDataPair>();
this.table.GetMatchingValues(messageBuffer, pairs);
for (int i = 0; i < pairs.Count; ++i)
{
if (pairs[i].filter.Filter2.Match(messageBuffer))
{
results.Add(pairs[i].data);
}
}
}
internal bool GetMatchingValue(Message message, out FilterData data, out bool addressMatched)
{
if (message == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
}
List<FilterDataPair> pairs = new List<FilterDataPair>();
addressMatched = this.table.GetMatchingValues(message, pairs);
FilterDataPair pair = null;
for (int i = 0; i < pairs.Count; ++i)
{
if (pairs[i].filter.Filter2.Match(message))
{
if (pair != null)
{
Collection<MessageFilter> matches = new Collection<MessageFilter>();
matches.Add(pair.filter);
matches.Add(pairs[i].filter);
throw TraceUtility.ThrowHelperError(new MultipleFilterMatchesException(SR.GetString(SR.FilterMultipleMatches), null, matches), message);
}
pair = pairs[i];
}
}
if (pair == null)
{
data = default(FilterData);
return false;
}
data = pair.data;
return true;
}
public bool GetMatchingValue(Message message, out FilterData data)
{
if (message == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
}
FilterDataPair pair = InnerMatch(message);
if (pair == null)
{
data = default(FilterData);
return false;
}
data = pair.data;
return true;
}
public bool GetMatchingValue(MessageBuffer messageBuffer, out FilterData data)
{
if (messageBuffer == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageBuffer");
}
FilterDataPair pair = InnerMatch(messageBuffer);
if (pair == null)
{
data = default(FilterData);
return false;
}
data = pair.data;
return true;
}
public bool GetMatchingFilter(Message message, out MessageFilter filter)
{
if (message == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
}
FilterDataPair pair = InnerMatch(message);
if (pair == null)
{
filter = null;
return false;
}
filter = pair.filter;
return true;
}
public bool GetMatchingFilter(MessageBuffer messageBuffer, out MessageFilter filter)
{
if (messageBuffer == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageBuffer");
}
FilterDataPair pair = InnerMatch(messageBuffer);
if (pair == null)
{
filter = null;
return false;
}
filter = pair.filter;
return true;
}
public bool GetMatchingFilters(Message message, ICollection<MessageFilter> results)
{
if (message == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
}
if (results == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("results");
}
int count = results.Count;
InnerMatch(message, results);
return count != results.Count;
}
public bool GetMatchingFilters(MessageBuffer messageBuffer, ICollection<MessageFilter> results)
{
if (messageBuffer == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageBuffer");
}
if (results == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("results");
}
int count = results.Count;
InnerMatch(messageBuffer, results);
return count != results.Count;
}
public bool GetMatchingValues(Message message, ICollection<FilterData> results)
{
if (message == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
}
if (results == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("results");
}
int count = results.Count;
InnerMatchData(message, results);
return count != results.Count;
}
public bool GetMatchingValues(MessageBuffer messageBuffer, ICollection<FilterData> results)
{
if (messageBuffer == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageBuffer");
}
if (results == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("results");
}
int count = results.Count;
InnerMatchData(messageBuffer, results);
return count != results.Count;
}
public bool Remove(MessageFilter filter)
{
if (filter == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter");
}
AndMessageFilter sbFilter = filter as AndMessageFilter;
if (sbFilter != null)
{
return Remove(sbFilter);
}
return false;
}
public bool Remove(KeyValuePair<MessageFilter, FilterData> item)
{
if (((ICollection<KeyValuePair<MessageFilter, FilterData>>)this.filters).Contains(item))
{
return Remove(item.Key);
}
return false;
}
public bool Remove(AndMessageFilter filter)
{
if (filter == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter");
}
if (this.filters.Remove(filter))
{
this.filterData.Remove(filter);
this.table.Remove(filter.Filter1);
return true;
}
return false;
}
internal class FilterDataPair
{
internal AndMessageFilter filter;
internal FilterData data;
internal FilterDataPair(AndMessageFilter filter, FilterData data)
{
this.filter = filter;
this.data = data;
}
}
public bool TryGetValue(MessageFilter filter, out FilterData data)
{
return this.filters.TryGetValue(filter, out data);
}
}
}

View File

@@ -0,0 +1,388 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.Diagnostics;
using System.Security;
using System.ServiceModel.Description;
using System.ServiceModel.Diagnostics;
using System.ServiceModel.Diagnostics.Application;
using System.Runtime;
class AsyncMethodInvoker : IOperationInvoker
{
MethodInfo beginMethod;
MethodInfo endMethod;
InvokeBeginDelegate invokeBeginDelegate;
InvokeEndDelegate invokeEndDelegate;
int inputParameterCount;
int outputParameterCount;
public AsyncMethodInvoker(MethodInfo beginMethod, MethodInfo endMethod)
{
if (beginMethod == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("beginMethod"));
if (endMethod == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("endMethod"));
this.beginMethod = beginMethod;
this.endMethod = endMethod;
}
public MethodInfo BeginMethod
{
get { return this.beginMethod; }
}
public MethodInfo EndMethod
{
get { return this.endMethod; }
}
public bool IsSynchronous
{
get { return false; }
}
public object[] AllocateInputs()
{
return EmptyArray.Allocate(this.InputParameterCount);
}
public object Invoke(object instance, object[] inputs, out object[] outputs)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
}
internal static void CreateActivityInfo(ref ServiceModelActivity activity, ref Activity boundActivity)
{
if (DiagnosticUtility.ShouldUseActivity)
{
activity = ServiceModelActivity.CreateAsyncActivity();
TraceUtility.UpdateAsyncOperationContextWithActivity(activity);
boundActivity = ServiceModelActivity.BoundOperation(activity, true);
}
else if (TraceUtility.MessageFlowTracingOnly)
{
Guid activityId = TraceUtility.GetReceivedActivityId(OperationContext.Current);
if (activityId != Guid.Empty)
{
DiagnosticTraceBase.ActivityId = activityId;
}
}
else if (TraceUtility.ShouldPropagateActivity)
{
//Message flow tracing only scenarios use a light-weight ActivityID management logic
Guid activityId = ActivityIdHeader.ExtractActivityId(OperationContext.Current.IncomingMessage);
if (activityId != Guid.Empty)
{
boundActivity = Activity.CreateActivity(activityId);
}
TraceUtility.UpdateAsyncOperationContextWithActivity(activityId);
}
}
public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
{
if (instance == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxNoServiceObject)));
if (inputs == null)
{
if (this.InputParameterCount > 0)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInputParametersToServiceNull, this.InputParameterCount)));
}
else if (inputs.Length != this.InputParameterCount)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxInputParametersToServiceInvalid, this.InputParameterCount, inputs.Length)));
StartOperationInvokePerformanceCounters(this.beginMethod.Name.Substring(ServiceReflector.BeginMethodNamePrefix.Length));
IAsyncResult returnValue;
bool callFailed = true;
bool callFaulted = false;
ServiceModelActivity activity = null;
try
{
Activity boundActivity = null;
CreateActivityInfo(ref activity, ref boundActivity);
StartOperationInvokeTrace(this.beginMethod.Name);
using (boundActivity)
{
if (DiagnosticUtility.ShouldUseActivity)
{
string activityName = null;
if (this.endMethod == null)
{
activityName = SR.GetString(SR.ActivityExecuteMethod,
this.beginMethod.DeclaringType.FullName, this.beginMethod.Name);
}
else
{
activityName = SR.GetString(SR.ActivityExecuteAsyncMethod,
this.beginMethod.DeclaringType.FullName, this.beginMethod.Name,
this.endMethod.DeclaringType.FullName, this.endMethod.Name);
}
ServiceModelActivity.Start(activity, activityName, ActivityType.ExecuteUserCode);
}
returnValue = this.InvokeBeginDelegate(instance, inputs, callback, state);
callFailed = false;
}
}
catch (System.Security.SecurityException e)
{
DiagnosticUtility.TraceHandledException(e, TraceEventType.Warning);
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(AuthorizationBehavior.CreateAccessDeniedFaultException());
}
catch (Exception e)
{
TraceUtility.TraceUserCodeException(e, this.beginMethod);
if (e is FaultException)
{
callFaulted = true;
callFailed = false;
}
throw;
}
finally
{
ServiceModelActivity.Stop(activity);
// An exception during the InvokeBegin will not call InvokeEnd,
// so we complete the trace and performance counters here.
if (callFailed || callFaulted)
{
StopOperationInvokeTrace(callFailed, callFaulted, this.EndMethod.Name);
StopOperationInvokePerformanceCounters(callFailed, callFaulted, endMethod.Name.Substring(ServiceReflector.EndMethodNamePrefix.Length));
}
}
return returnValue;
}
internal static void GetActivityInfo(ref ServiceModelActivity activity, ref Activity boundOperation)
{
if (TraceUtility.MessageFlowTracingOnly)
{
if (null != OperationContext.Current)
{
Guid activityId = TraceUtility.GetReceivedActivityId(OperationContext.Current);
if (activityId != Guid.Empty)
{
DiagnosticTraceBase.ActivityId = activityId;
}
}
}
else if (DiagnosticUtility.ShouldUseActivity || TraceUtility.ShouldPropagateActivity)
{
object activityInfo = TraceUtility.ExtractAsyncOperationContextActivity();
if (activityInfo != null)
{
if (DiagnosticUtility.ShouldUseActivity)
{
activity = activityInfo as ServiceModelActivity;
boundOperation = ServiceModelActivity.BoundOperation(activity, true);
}
else if (TraceUtility.ShouldPropagateActivity)
{
if (activityInfo is Guid)
{
Guid activityId = (Guid)activityInfo;
boundOperation = Activity.CreateActivity(activityId);
}
}
}
}
}
public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
{
object returnVal;
if (instance == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxNoServiceObject)));
outputs = EmptyArray.Allocate(this.OutputParameterCount);
bool callFailed = true;
bool callFaulted = false;
ServiceModelActivity activity = null;
try
{
Activity boundOperation = null;
GetActivityInfo(ref activity, ref boundOperation);
using (boundOperation)
{
returnVal = this.InvokeEndDelegate(instance, outputs, result);
callFailed = false;
}
}
catch (SecurityException e)
{
DiagnosticUtility.TraceHandledException(e, TraceEventType.Warning);
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(AuthorizationBehavior.CreateAccessDeniedFaultException());
}
catch (FaultException)
{
callFaulted = true;
callFailed = false;
throw;
}
finally
{
ServiceModelActivity.Stop(activity);
StopOperationInvokeTrace(callFailed, callFaulted, this.endMethod.Name);
StopOperationInvokePerformanceCounters(callFailed, callFaulted, this.endMethod.Name.Substring(ServiceReflector.EndMethodNamePrefix.Length));
}
return returnVal;
}
internal static void StartOperationInvokeTrace(string methodName)
{
if (TD.OperationInvokedIsEnabled())
{
OperationContext context = OperationContext.Current;
EventTraceActivity eventTraceActivity = null;
if (context != null && context.IncomingMessage != null)
{
eventTraceActivity = EventTraceActivityHelper.TryExtractActivity(context.IncomingMessage);
}
if (TD.OperationInvokedIsEnabled())
{
TD.OperationInvoked(eventTraceActivity, methodName, TraceUtility.GetCallerInfo(OperationContext.Current));
}
if (TD.OperationCompletedIsEnabled() || TD.OperationFaultedIsEnabled() || TD.OperationFailedIsEnabled())
{
TraceUtility.UpdateAsyncOperationContextWithStartTime(eventTraceActivity, DateTime.UtcNow.Ticks);
}
}
}
internal static void StopOperationInvokeTrace(bool callFailed, bool callFaulted, string methodName)
{
if (!(TD.OperationCompletedIsEnabled() ||
TD.OperationFaultedIsEnabled() ||
TD.OperationFailedIsEnabled()))
{
return;
}
EventTraceActivity eventTraceActivity;
long startTime;
TraceUtility.ExtractAsyncOperationStartTime(out eventTraceActivity, out startTime);
long duration = TraceUtility.GetUtcBasedDurationForTrace(startTime);
if (callFailed)
{
if (TD.OperationFailedIsEnabled())
{
TD.OperationFailed(eventTraceActivity, methodName, duration);
}
}
else if (callFaulted)
{
if (TD.OperationFaultedIsEnabled())
{
TD.OperationFaulted(eventTraceActivity, methodName, duration);
}
}
else
{
if (TD.OperationCompletedIsEnabled())
{
TD.OperationCompleted(eventTraceActivity, methodName, duration);
}
}
}
internal static void StartOperationInvokePerformanceCounters(string methodName)
{
if (PerformanceCounters.PerformanceCountersEnabled)
{
PerformanceCounters.MethodCalled(methodName);
}
}
internal static void StopOperationInvokePerformanceCounters(bool callFailed, bool callFaulted, string methodName)
{
if (PerformanceCounters.PerformanceCountersEnabled)
{
if (callFailed)
{
PerformanceCounters.MethodReturnedError(methodName);
}
else if (callFaulted)
{
PerformanceCounters.MethodReturnedFault(methodName);
}
else
{
PerformanceCounters.MethodReturnedSuccess(methodName);
}
}
}
InvokeBeginDelegate InvokeBeginDelegate
{
get
{
EnsureIsInitialized();
return invokeBeginDelegate;
}
}
InvokeEndDelegate InvokeEndDelegate
{
get
{
EnsureIsInitialized();
return invokeEndDelegate;
}
}
int InputParameterCount
{
get
{
EnsureIsInitialized();
return this.inputParameterCount;
}
}
int OutputParameterCount
{
get
{
EnsureIsInitialized();
return this.outputParameterCount;
}
}
void EnsureIsInitialized()
{
if (this.invokeBeginDelegate == null)
{
// Only pass locals byref because InvokerUtil may store temporary results in the byref.
// If two threads both reference this.count, temporary results may interact.
int inputParameterCount;
InvokeBeginDelegate invokeBeginDelegate = new InvokerUtil().GenerateInvokeBeginDelegate(this.beginMethod, out inputParameterCount);
this.inputParameterCount = inputParameterCount;
int outputParameterCount;
InvokeEndDelegate invokeEndDelegate = new InvokerUtil().GenerateInvokeEndDelegate(this.endMethod, out outputParameterCount);
this.outputParameterCount = outputParameterCount;
this.invokeEndDelegate = invokeEndDelegate;
this.invokeBeginDelegate = invokeBeginDelegate; // must set this last due to ----
}
}
}
}

View File

@@ -0,0 +1,141 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.CompilerServices;
using System.Messaging;
using System.ServiceModel.Security;
using System.Collections.ObjectModel;
using System.IdentityModel.Policy;
using System.Runtime;
using System.ServiceModel.Diagnostics;
using System.Diagnostics;
using System.Globalization;
sealed class AuthenticationBehavior
{
ServiceAuthenticationManager serviceAuthenticationManager;
AuditLogLocation auditLogLocation;
bool suppressAuditFailure;
AuditLevel messageAuthenticationAuditLevel;
AuthenticationBehavior(ServiceAuthenticationManager authenticationManager)
{
this.serviceAuthenticationManager = authenticationManager;
}
public void Authenticate(ref MessageRpc rpc)
{
SecurityMessageProperty security = SecurityMessageProperty.GetOrCreate(rpc.Request);
ReadOnlyCollection<IAuthorizationPolicy> authPolicy = security.ServiceSecurityContext.AuthorizationPolicies;
try
{
authPolicy = this.serviceAuthenticationManager.Authenticate(security.ServiceSecurityContext.AuthorizationPolicies, rpc.Channel.ListenUri, ref rpc.Request);
if (authPolicy == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.AuthenticationManagerShouldNotReturnNull)));
}
}
catch (Exception ex)
{
if (Fx.IsFatal(ex))
{
throw;
}
if (PerformanceCounters.PerformanceCountersEnabled)
{
PerformanceCounters.AuthenticationFailed(rpc.Request, rpc.Channel.ListenUri);
}
if (AuditLevel.Failure == (this.messageAuthenticationAuditLevel & AuditLevel.Failure))
{
try
{
string primaryIdentity;
AuthorizationContext authContext = security.ServiceSecurityContext.AuthorizationContext;
if (authContext != null)
{
primaryIdentity = SecurityUtils.GetIdentityNamesFromContext(authContext);
}
else
{
primaryIdentity = SecurityUtils.AnonymousIdentity.Name;
}
SecurityAuditHelper.WriteMessageAuthenticationFailureEvent(this.auditLogLocation,
this.suppressAuditFailure, rpc.Request, rpc.Channel.ListenUri, rpc.Request.Headers.Action,
primaryIdentity, ex);
}
#pragma warning suppress 56500
catch (Exception auditException)
{
if (Fx.IsFatal(auditException))
throw;
DiagnosticUtility.TraceHandledException(auditException, TraceEventType.Error);
}
}
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateFailedAuthenticationFaultException());
}
rpc.Request.Properties.Security.ServiceSecurityContext.AuthorizationPolicies = authPolicy;
if (AuditLevel.Success == (this.messageAuthenticationAuditLevel & AuditLevel.Success))
{
string primaryIdentity;
AuthorizationContext authContext = security.ServiceSecurityContext.AuthorizationContext;
if (authContext != null)
{
primaryIdentity = SecurityUtils.GetIdentityNamesFromContext(authContext);
}
else
{
primaryIdentity = SecurityUtils.AnonymousIdentity.Name;
}
SecurityAuditHelper.WriteMessageAuthenticationSuccessEvent(this.auditLogLocation,
this.suppressAuditFailure, rpc.Request, rpc.Channel.ListenUri, rpc.Request.Headers.Action,
primaryIdentity);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
static AuthenticationBehavior CreateAuthenticationBehavior(DispatchRuntime dispatch)
{
AuthenticationBehavior authenticationBehavior = new AuthenticationBehavior(dispatch.ServiceAuthenticationManager);
authenticationBehavior.auditLogLocation = dispatch.SecurityAuditLogLocation;
authenticationBehavior.suppressAuditFailure = dispatch.SuppressAuditFailure;
authenticationBehavior.messageAuthenticationAuditLevel = dispatch.MessageAuthenticationAuditLevel;
return authenticationBehavior;
}
public static AuthenticationBehavior TryCreate(DispatchRuntime dispatch)
{
if (dispatch == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("dispatch");
if (!dispatch.RequiresAuthentication)
return null;
return CreateAuthenticationBehavior(dispatch);
}
internal static Exception CreateFailedAuthenticationFaultException()
{
// always use default version?
SecurityVersion wss = SecurityVersion.Default;
FaultCode faultCode = FaultCode.CreateSenderFaultCode(wss.InvalidSecurityFaultCode.Value, wss.HeaderNamespace.Value);
FaultReason faultReason = new FaultReason(SR.GetString(SR.AuthenticationOfClientFailed), CultureInfo.CurrentCulture);
return new FaultException(faultReason, faultCode);
}
}
}

View File

@@ -0,0 +1,150 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IdentityModel.Policy;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.ServiceModel;
using System.ServiceModel.Diagnostics;
using System.ServiceModel.Diagnostics.Application;
using System.ServiceModel.Security;
sealed class AuthorizationBehavior
{
static ServiceAuthorizationManager DefaultServiceAuthorizationManager = new ServiceAuthorizationManager();
ReadOnlyCollection<IAuthorizationPolicy> externalAuthorizationPolicies;
ServiceAuthorizationManager serviceAuthorizationManager;
AuditLogLocation auditLogLocation;
bool suppressAuditFailure;
AuditLevel serviceAuthorizationAuditLevel;
AuthorizationBehavior() { }
public void Authorize(ref MessageRpc rpc)
{
if (TD.DispatchMessageBeforeAuthorizationIsEnabled())
{
TD.DispatchMessageBeforeAuthorization(rpc.EventTraceActivity);
}
SecurityMessageProperty security = SecurityMessageProperty.GetOrCreate(rpc.Request);
security.ExternalAuthorizationPolicies = this.externalAuthorizationPolicies;
ServiceAuthorizationManager serviceAuthorizationManager = this.serviceAuthorizationManager ?? DefaultServiceAuthorizationManager;
try
{
if (!serviceAuthorizationManager.CheckAccess(rpc.OperationContext, ref rpc.Request))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateAccessDeniedFaultException());
}
}
catch (Exception ex)
{
if (Fx.IsFatal(ex))
{
throw;
}
if (PerformanceCounters.PerformanceCountersEnabled)
{
PerformanceCounters.AuthorizationFailed(rpc.Operation.Name);
}
if (AuditLevel.Failure == (this.serviceAuthorizationAuditLevel & AuditLevel.Failure))
{
try
{
string primaryIdentity;
string authContextId = null;
AuthorizationContext authContext = security.ServiceSecurityContext.AuthorizationContext;
if (authContext != null)
{
primaryIdentity = SecurityUtils.GetIdentityNamesFromContext(authContext);
authContextId = authContext.Id;
}
else
{
primaryIdentity = SecurityUtils.AnonymousIdentity.Name;
authContextId = "<null>";
}
SecurityAuditHelper.WriteServiceAuthorizationFailureEvent(this.auditLogLocation,
this.suppressAuditFailure, rpc.Request, rpc.Request.Headers.To, rpc.Request.Headers.Action,
primaryIdentity, authContextId,
serviceAuthorizationManager == DefaultServiceAuthorizationManager ? "<default>" : serviceAuthorizationManager.GetType().Name,
ex);
}
#pragma warning suppress 56500
catch (Exception auditException)
{
if (Fx.IsFatal(auditException))
throw;
DiagnosticUtility.TraceHandledException(auditException, TraceEventType.Error);
}
}
throw;
}
if (AuditLevel.Success == (this.serviceAuthorizationAuditLevel & AuditLevel.Success))
{
string primaryIdentity;
string authContextId;
AuthorizationContext authContext = security.ServiceSecurityContext.AuthorizationContext;
if (authContext != null)
{
primaryIdentity = SecurityUtils.GetIdentityNamesFromContext(authContext);
authContextId = authContext.Id;
}
else
{
primaryIdentity = SecurityUtils.AnonymousIdentity.Name;
authContextId = "<null>";
}
SecurityAuditHelper.WriteServiceAuthorizationSuccessEvent(this.auditLogLocation,
this.suppressAuditFailure, rpc.Request, rpc.Request.Headers.To, rpc.Request.Headers.Action,
primaryIdentity, authContextId,
serviceAuthorizationManager == DefaultServiceAuthorizationManager ? "<default>" : serviceAuthorizationManager.GetType().Name);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
static AuthorizationBehavior CreateAuthorizationBehavior(DispatchRuntime dispatch)
{
AuthorizationBehavior behavior = new AuthorizationBehavior();
behavior.externalAuthorizationPolicies = dispatch.ExternalAuthorizationPolicies;
behavior.serviceAuthorizationManager = dispatch.ServiceAuthorizationManager;
behavior.auditLogLocation = dispatch.SecurityAuditLogLocation;
behavior.suppressAuditFailure = dispatch.SuppressAuditFailure;
behavior.serviceAuthorizationAuditLevel = dispatch.ServiceAuthorizationAuditLevel;
return behavior;
}
public static AuthorizationBehavior TryCreate(DispatchRuntime dispatch)
{
if (dispatch == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("dispatch"));
if (!dispatch.RequiresAuthorization)
return null;
return CreateAuthorizationBehavior(dispatch);
}
internal static Exception CreateAccessDeniedFaultException()
{
// always use default version?
SecurityVersion wss = SecurityVersion.Default;
FaultCode faultCode = FaultCode.CreateSenderFaultCode(wss.FailedAuthenticationFaultCode.Value, wss.HeaderNamespace.Value);
FaultReason faultReason = new FaultReason(SR.GetString(SR.AccessDenied), CultureInfo.CurrentCulture);
return new FaultException(faultReason, faultCode);
}
}
}

View File

@@ -0,0 +1,275 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System;
using System.Collections.Generic;
using System.ServiceModel.Diagnostics;
using System.Runtime;
using System.ServiceModel.Channels;
using System.Threading;
class BufferedReceiveBinder : IChannelBinder
{
static Action<object> tryReceive = new Action<object>(BufferedReceiveBinder.TryReceive);
static AsyncCallback tryReceiveCallback = Fx.ThunkCallback(new AsyncCallback(TryReceiveCallback));
IChannelBinder channelBinder;
InputQueue<RequestContextWrapper> inputQueue;
[Fx.Tag.SynchronizationObject(Blocking = true, Kind = Fx.Tag.SynchronizationKind.InterlockedNoSpin)]
int pendingOperationSemaphore;
public BufferedReceiveBinder(IChannelBinder channelBinder)
{
this.channelBinder = channelBinder;
this.inputQueue = new InputQueue<RequestContextWrapper>();
}
public IChannel Channel
{
get { return this.channelBinder.Channel; }
}
public bool HasSession
{
get { return this.channelBinder.HasSession; }
}
public Uri ListenUri
{
get { return this.channelBinder.ListenUri; }
}
public EndpointAddress LocalAddress
{
get { return this.channelBinder.LocalAddress; }
}
public EndpointAddress RemoteAddress
{
get { return this.channelBinder.RemoteAddress; }
}
public void Abort()
{
this.inputQueue.Close();
this.channelBinder.Abort();
}
public void CloseAfterFault(TimeSpan timeout)
{
this.inputQueue.Close();
this.channelBinder.CloseAfterFault(timeout);
}
// Locking:
// Only 1 channelBinder operation call should be active at any given time. All future calls
// will wait on the inputQueue. The semaphore is always released right before the Dispatch on the inputQueue.
// This protects a new call racing with an existing operation that is just about to fully complete.
public bool TryReceive(TimeSpan timeout, out RequestContext requestContext)
{
if (Interlocked.CompareExchange(ref this.pendingOperationSemaphore, 1, 0) == 0)
{
ActionItem.Schedule(tryReceive, this);
}
RequestContextWrapper wrapper;
bool success = this.inputQueue.Dequeue(timeout, out wrapper);
if (success && wrapper != null)
{
requestContext = wrapper.RequestContext;
}
else
{
requestContext = null;
}
return success;
}
public IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state)
{
if (Interlocked.CompareExchange(ref this.pendingOperationSemaphore, 1, 0) == 0)
{
IAsyncResult result = this.channelBinder.BeginTryReceive(timeout, tryReceiveCallback, this);
if (result.CompletedSynchronously)
{
HandleEndTryReceive(result);
}
}
return this.inputQueue.BeginDequeue(timeout, callback, state);
}
public bool EndTryReceive(IAsyncResult result, out RequestContext requestContext)
{
RequestContextWrapper wrapper;
bool success = this.inputQueue.EndDequeue(result, out wrapper);
if (success && wrapper != null)
{
requestContext = wrapper.RequestContext;
}
else
{
requestContext = null;
}
return success;
}
public RequestContext CreateRequestContext(Message message)
{
return this.channelBinder.CreateRequestContext(message);
}
public void Send(Message message, TimeSpan timeout)
{
this.channelBinder.Send(message, timeout);
}
public IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state)
{
return this.channelBinder.BeginSend(message, timeout, callback, state);
}
public void EndSend(IAsyncResult result)
{
this.channelBinder.EndSend(result);
}
public Message Request(Message message, TimeSpan timeout)
{
return this.channelBinder.Request(message, timeout);
}
public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state)
{
return this.channelBinder.BeginRequest(message, timeout, callback, state);
}
public Message EndRequest(IAsyncResult result)
{
return this.channelBinder.EndRequest(result);
}
public bool WaitForMessage(TimeSpan timeout)
{
return this.channelBinder.WaitForMessage(timeout);
}
public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state)
{
return this.channelBinder.BeginWaitForMessage(timeout, callback, state);
}
public bool EndWaitForMessage(IAsyncResult result)
{
return this.channelBinder.EndWaitForMessage(result);
}
internal void InjectRequest(RequestContext requestContext)
{
// Reuse the existing requestContext
this.inputQueue.EnqueueAndDispatch(new RequestContextWrapper(requestContext));
}
//
// TryReceive threads
//
static void TryReceive(object state)
{
BufferedReceiveBinder binder = (BufferedReceiveBinder)state;
RequestContext requestContext;
bool requiresDispatch = false;
try
{
if (binder.channelBinder.TryReceive(TimeSpan.MaxValue, out requestContext))
{
requiresDispatch = binder.inputQueue.EnqueueWithoutDispatch(new RequestContextWrapper(requestContext), null);
}
}
catch (Exception exception)
{
if (Fx.IsFatal(exception))
{
throw;
}
requiresDispatch = binder.inputQueue.EnqueueWithoutDispatch(exception, null);
}
finally
{
Interlocked.Exchange(ref binder.pendingOperationSemaphore, 0);
if (requiresDispatch)
{
binder.inputQueue.Dispatch();
}
}
}
static void TryReceiveCallback(IAsyncResult result)
{
if (result.CompletedSynchronously)
{
return;
}
HandleEndTryReceive(result);
}
static void HandleEndTryReceive(IAsyncResult result)
{
BufferedReceiveBinder binder = (BufferedReceiveBinder)result.AsyncState;
RequestContext requestContext;
bool requiresDispatch = false;
try
{
if (binder.channelBinder.EndTryReceive(result, out requestContext))
{
requiresDispatch = binder.inputQueue.EnqueueWithoutDispatch(new RequestContextWrapper(requestContext), null);
}
}
catch (Exception exception)
{
if (Fx.IsFatal(exception))
{
throw;
}
requiresDispatch = binder.inputQueue.EnqueueWithoutDispatch(exception, null);
}
finally
{
Interlocked.Exchange(ref binder.pendingOperationSemaphore, 0);
if (requiresDispatch)
{
binder.inputQueue.Dispatch();
}
}
}
// A RequestContext may be 'null' (some pieces of ChannelHandler depend on this) but the InputQueue
// will not allow null items to be enqueued. Wrap the RequestContexts in another object to
// facilitate this semantic
class RequestContextWrapper
{
public RequestContextWrapper(RequestContext requestContext)
{
this.RequestContext = requestContext;
}
public RequestContext RequestContext
{
get;
private set;
}
}
}
}

View File

@@ -0,0 +1,42 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System;
using System.ServiceModel.Channels;
public abstract class ChannelDispatcherBase : CommunicationObject
{
public abstract ServiceHostBase Host { get; }
public abstract IChannelListener Listener { get; }
internal void AttachInternal(ServiceHostBase host)
{
this.Attach(host);
}
protected virtual void Attach(ServiceHostBase host)
{
}
internal void DetachInternal(ServiceHostBase host)
{
this.Detach(host);
}
protected virtual void Detach(ServiceHostBase host)
{
}
public virtual void CloseInput()
{
}
internal virtual void CloseInput(TimeSpan timeout)
{
CloseInput(); // back-compat
}
}
}

View File

@@ -0,0 +1,83 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Runtime.Serialization;
public class ChannelDispatcherCollection : SynchronizedCollection<ChannelDispatcherBase>
{
ServiceHostBase service;
internal ChannelDispatcherCollection(ServiceHostBase service, object syncRoot)
: base(syncRoot)
{
if (service == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("service");
this.service = service;
}
protected override void ClearItems()
{
ChannelDispatcherBase[] array = new ChannelDispatcherBase[this.Count];
this.CopyTo(array, 0);
base.ClearItems();
if (this.service != null)
{
foreach (ChannelDispatcherBase channelDispatcher in array)
this.service.OnRemoveChannelDispatcher(channelDispatcher);
}
}
protected override void InsertItem(int index, ChannelDispatcherBase item)
{
if (this.service != null)
{
if (this.service.State == CommunicationState.Closed)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ObjectDisposedException(this.service.GetType().ToString()));
this.service.OnAddChannelDispatcher(item);
}
base.InsertItem(index, item);
}
protected override void RemoveItem(int index)
{
ChannelDispatcherBase channelDispatcher = this.Items[index];
base.RemoveItem(index);
if (this.service != null)
this.service.OnRemoveChannelDispatcher(channelDispatcher);
}
protected override void SetItem(int index, ChannelDispatcherBase item)
{
if (this.service != null)
{
if (this.service.State == CommunicationState.Closed)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ObjectDisposedException(this.service.GetType().ToString()));
}
if (this.service != null)
this.service.OnAddChannelDispatcher(item);
ChannelDispatcherBase old;
lock (this.SyncRoot)
{
old = this.Items[index];
base.SetItem(index, item);
}
if (this.service != null)
this.service.OnRemoveChannelDispatcher(old);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,304 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System;
using System.Reflection;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Compat", Justification = "Compat is an accepted abbreviation")]
[EditorBrowsable(EditorBrowsableState.Never)]
public class ClientOperationCompatBase
{
internal ClientOperationCompatBase() { }
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.", true)]
public IList<IParameterInspector> ParameterInspectors
{
get
{
return this.parameterInspectors;
}
}
internal SynchronizedCollection<IParameterInspector> parameterInspectors;
}
public sealed class ClientOperation : ClientOperationCompatBase
{
string action;
SynchronizedCollection<FaultContractInfo> faultContractInfos;
bool serializeRequest;
bool deserializeReply;
IClientMessageFormatter formatter;
IClientFaultFormatter faultFormatter;
bool isInitiating = true;
bool isOneWay;
bool isTerminating;
bool isSessionOpenNotificationEnabled;
string name;
ClientRuntime parent;
string replyAction;
MethodInfo beginMethod;
MethodInfo endMethod;
MethodInfo syncMethod;
MethodInfo taskMethod;
Type taskTResult;
bool isFaultFormatterSetExplicit = false;
public ClientOperation(ClientRuntime parent, string name, string action)
: this(parent, name, action, null)
{
}
public ClientOperation(ClientRuntime parent, string name, string action, string replyAction)
{
if (parent == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parent");
if (name == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("name");
this.parent = parent;
this.name = name;
this.action = action;
this.replyAction = replyAction;
this.faultContractInfos = parent.NewBehaviorCollection<FaultContractInfo>();
this.parameterInspectors = parent.NewBehaviorCollection<IParameterInspector>();
}
public string Action
{
get { return this.action; }
}
public SynchronizedCollection<FaultContractInfo> FaultContractInfos
{
get { return this.faultContractInfos; }
}
public MethodInfo BeginMethod
{
get { return this.beginMethod; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.beginMethod = value;
}
}
}
public MethodInfo EndMethod
{
get { return this.endMethod; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.endMethod = value;
}
}
}
public MethodInfo SyncMethod
{
get { return this.syncMethod; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.syncMethod = value;
}
}
}
public IClientMessageFormatter Formatter
{
get { return this.formatter; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.formatter = value;
}
}
}
internal IClientFaultFormatter FaultFormatter
{
get
{
if (this.faultFormatter == null)
{
this.faultFormatter = new DataContractSerializerFaultFormatter(this.faultContractInfos);
}
return this.faultFormatter;
}
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.faultFormatter = value;
this.isFaultFormatterSetExplicit = true;
}
}
}
internal bool IsFaultFormatterSetExplicit
{
get
{
return this.isFaultFormatterSetExplicit;
}
}
internal IClientMessageFormatter InternalFormatter
{
get { return this.formatter; }
set { this.formatter = value; }
}
public bool IsInitiating
{
get { return this.isInitiating; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.isInitiating = value;
}
}
}
public bool IsOneWay
{
get { return this.isOneWay; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.isOneWay = value;
}
}
}
public bool IsTerminating
{
get { return this.isTerminating; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.isTerminating = value;
}
}
}
public string Name
{
get { return this.name; }
}
public ICollection<IParameterInspector> ClientParameterInspectors
{
get { return this.ParameterInspectors; }
}
[EditorBrowsable(EditorBrowsableState.Never)]
public new SynchronizedCollection<IParameterInspector> ParameterInspectors
{
get { return this.parameterInspectors; }
}
public ClientRuntime Parent
{
get { return this.parent; }
}
public string ReplyAction
{
get { return this.replyAction; }
}
public bool SerializeRequest
{
get { return this.serializeRequest; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.serializeRequest = value;
}
}
}
public bool DeserializeReply
{
get { return this.deserializeReply; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.deserializeReply = value;
}
}
}
public MethodInfo TaskMethod
{
get { return this.taskMethod; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.taskMethod = value;
}
}
}
public Type TaskTResult
{
get { return this.taskTResult; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.taskTResult = value;
}
}
}
internal bool IsSessionOpenNotificationEnabled
{
get { return this.isSessionOpenNotificationEnabled; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.isSessionOpenNotificationEnabled = value;
}
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,296 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System;
using System.Collections.Generic;
using System.Runtime;
using System.ServiceModel;
using System.Threading;
class ConcurrencyBehavior
{
ConcurrencyMode concurrencyMode;
bool enforceOrderedReceive;
bool supportsTransactedBatch;
internal ConcurrencyBehavior(DispatchRuntime runtime)
{
this.concurrencyMode = runtime.ConcurrencyMode;
this.enforceOrderedReceive = runtime.EnsureOrderedDispatch;
this.supportsTransactedBatch = ConcurrencyBehavior.SupportsTransactedBatch(runtime.ChannelDispatcher);
}
static bool SupportsTransactedBatch(ChannelDispatcher channelDispatcher)
{
return channelDispatcher.IsTransactedReceive && (channelDispatcher.MaxTransactedBatchSize > 0);
}
internal bool IsConcurrent(ref MessageRpc rpc)
{
return IsConcurrent(this.concurrencyMode, this.enforceOrderedReceive, rpc.Channel.HasSession, this.supportsTransactedBatch);
}
internal static bool IsConcurrent(ConcurrencyMode concurrencyMode, bool ensureOrderedDispatch, bool hasSession, bool supportsTransactedBatch)
{
if (supportsTransactedBatch)
{
return false;
}
if (concurrencyMode != ConcurrencyMode.Single)
{
return true;
}
if (hasSession)
{
return false;
}
if (ensureOrderedDispatch)
{
return false;
}
return true;
}
internal static bool IsConcurrent(ChannelDispatcher runtime, bool hasSession)
{
bool isConcurrencyModeSingle = true;
if (ConcurrencyBehavior.SupportsTransactedBatch(runtime))
{
return false;
}
foreach (EndpointDispatcher endpointDispatcher in runtime.Endpoints)
{
if (endpointDispatcher.DispatchRuntime.EnsureOrderedDispatch)
{
return false;
}
if (endpointDispatcher.DispatchRuntime.ConcurrencyMode != ConcurrencyMode.Single)
{
isConcurrencyModeSingle = false;
}
}
if (!isConcurrencyModeSingle)
{
return true;
}
if (!hasSession)
{
return true;
}
return false;
}
internal void LockInstance(ref MessageRpc rpc)
{
if (this.concurrencyMode != ConcurrencyMode.Multiple)
{
ConcurrencyInstanceContextFacet resource = rpc.InstanceContext.Concurrency;
lock (rpc.InstanceContext.ThisLock)
{
if (!resource.Locked)
{
resource.Locked = true;
}
else
{
MessageRpcWaiter waiter = new MessageRpcWaiter(rpc.Pause());
resource.EnqueueNewMessage(waiter);
}
}
if (this.concurrencyMode == ConcurrencyMode.Reentrant)
{
rpc.OperationContext.IsServiceReentrant = true;
}
}
}
internal void UnlockInstance(ref MessageRpc rpc)
{
if (this.concurrencyMode != ConcurrencyMode.Multiple)
{
ConcurrencyBehavior.UnlockInstance(rpc.InstanceContext);
}
}
internal static void UnlockInstanceBeforeCallout(OperationContext operationContext)
{
if (operationContext != null && operationContext.IsServiceReentrant)
{
ConcurrencyBehavior.UnlockInstance(operationContext.InstanceContext);
}
}
static void UnlockInstance(InstanceContext instanceContext)
{
ConcurrencyInstanceContextFacet resource = instanceContext.Concurrency;
lock (instanceContext.ThisLock)
{
if (resource.HasWaiters)
{
IWaiter nextWaiter = resource.DequeueWaiter();
nextWaiter.Signal();
}
else
{
//We have no pending Callouts and no new Messages to process
resource.Locked = false;
}
}
}
internal static void LockInstanceAfterCallout(OperationContext operationContext)
{
if (operationContext != null)
{
InstanceContext instanceContext = operationContext.InstanceContext;
if (operationContext.IsServiceReentrant)
{
ConcurrencyInstanceContextFacet resource = instanceContext.Concurrency;
ThreadWaiter waiter = null;
lock (instanceContext.ThisLock)
{
if (!resource.Locked)
{
resource.Locked = true;
}
else
{
waiter = new ThreadWaiter();
resource.EnqueueCalloutMessage(waiter);
}
}
if (waiter != null)
{
waiter.Wait();
}
}
}
}
internal interface IWaiter
{
void Signal();
}
class MessageRpcWaiter : IWaiter
{
IResumeMessageRpc resume;
internal MessageRpcWaiter(IResumeMessageRpc resume)
{
this.resume = resume;
}
void IWaiter.Signal()
{
try
{
bool alreadyResumedNoLock;
this.resume.Resume(out alreadyResumedNoLock);
if (alreadyResumedNoLock)
{
Fx.Assert("ConcurrencyBehavior resumed more than once for same call.");
}
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e);
}
}
}
class ThreadWaiter : IWaiter
{
ManualResetEvent wait = new ManualResetEvent(false);
void IWaiter.Signal()
{
this.wait.Set();
}
internal void Wait()
{
this.wait.WaitOne();
this.wait.Close();
}
}
}
internal class ConcurrencyInstanceContextFacet
{
internal bool Locked;
Queue<ConcurrencyBehavior.IWaiter> calloutMessageQueue;
Queue<ConcurrencyBehavior.IWaiter> newMessageQueue;
internal bool HasWaiters
{
get
{
return (((this.calloutMessageQueue != null) && (this.calloutMessageQueue.Count > 0)) ||
((this.newMessageQueue != null) && (this.newMessageQueue.Count > 0)));
}
}
ConcurrencyBehavior.IWaiter DequeueFrom(Queue<ConcurrencyBehavior.IWaiter> queue)
{
ConcurrencyBehavior.IWaiter waiter = queue.Dequeue();
if (queue.Count == 0)
{
queue.TrimExcess();
}
return waiter;
}
internal ConcurrencyBehavior.IWaiter DequeueWaiter()
{
// Finishing old work takes precedence over new work.
if ((this.calloutMessageQueue != null) && (this.calloutMessageQueue.Count > 0))
{
return this.DequeueFrom(this.calloutMessageQueue);
}
else
{
return this.DequeueFrom(this.newMessageQueue);
}
}
internal void EnqueueNewMessage(ConcurrencyBehavior.IWaiter waiter)
{
if (this.newMessageQueue == null)
this.newMessageQueue = new Queue<ConcurrencyBehavior.IWaiter>();
this.newMessageQueue.Enqueue(waiter);
}
internal void EnqueueCalloutMessage(ConcurrencyBehavior.IWaiter waiter)
{
if (this.calloutMessageQueue == null)
this.calloutMessageQueue = new Queue<ConcurrencyBehavior.IWaiter>();
this.calloutMessageQueue.Enqueue(waiter);
}
}
}

View File

@@ -0,0 +1,28 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Runtime.Serialization;
using System.Xml;
using System.Reflection;
using System.Diagnostics;
namespace System.ServiceModel.Dispatcher
{
class DataContractSerializerFaultFormatter : FaultFormatter
{
internal DataContractSerializerFaultFormatter(Type[] detailTypes)
: base(detailTypes)
{
}
internal DataContractSerializerFaultFormatter(SynchronizedCollection<FaultContractInfo> faultContractInfoCollection)
: base(faultContractInfoCollection)
{
}
}
}

View File

@@ -0,0 +1,104 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Runtime.Serialization;
using System.Collections.ObjectModel;
using System.Collections.Generic;
internal class DataContractSerializerServiceBehavior : IServiceBehavior, IEndpointBehavior
{
bool ignoreExtensionDataObject;
int maxItemsInObjectGraph;
internal DataContractSerializerServiceBehavior(bool ignoreExtensionDataObject, int maxItemsInObjectGraph)
{
this.ignoreExtensionDataObject = ignoreExtensionDataObject;
this.maxItemsInObjectGraph = maxItemsInObjectGraph;
}
public bool IgnoreExtensionDataObject
{
get { return this.ignoreExtensionDataObject; }
set { this.ignoreExtensionDataObject = value; }
}
public int MaxItemsInObjectGraph
{
get { return this.maxItemsInObjectGraph; }
set { this.maxItemsInObjectGraph = value; }
}
void IServiceBehavior.Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
{
}
void IServiceBehavior.AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
{
}
void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
{
ApplySerializationSettings(description, ignoreExtensionDataObject, maxItemsInObjectGraph);
}
void IEndpointBehavior.Validate(ServiceEndpoint serviceEndpoint)
{
}
void IEndpointBehavior.AddBindingParameters(ServiceEndpoint serviceEndpoint, BindingParameterCollection parameters)
{
}
void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime clientRuntime)
{
ApplySerializationSettings(serviceEndpoint, ignoreExtensionDataObject, maxItemsInObjectGraph);
}
void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher)
{
ApplySerializationSettings(serviceEndpoint, ignoreExtensionDataObject, maxItemsInObjectGraph);
}
internal static void ApplySerializationSettings(ServiceDescription description, bool ignoreExtensionDataObject, int maxItemsInObjectGraph)
{
foreach (ServiceEndpoint endpoint in description.Endpoints)
{
if (!endpoint.InternalIsSystemEndpoint(description))
{
ApplySerializationSettings(endpoint, ignoreExtensionDataObject, maxItemsInObjectGraph);
}
}
}
internal static void ApplySerializationSettings(ServiceEndpoint endpoint, bool ignoreExtensionDataObject, int maxItemsInObjectGraph)
{
foreach (OperationDescription operation in endpoint.Contract.Operations)
{
foreach (IOperationBehavior ob in operation.Behaviors)
{
if (ob is DataContractSerializerOperationBehavior)
{
DataContractSerializerOperationBehavior behavior = (DataContractSerializerOperationBehavior)ob;
if (behavior != null)
{
if (!behavior.IgnoreExtensionDataObjectSetExplicit)
{
behavior.ignoreExtensionDataObject = ignoreExtensionDataObject;
}
if (!behavior.MaxItemsInObjectGraphSetExplicit)
{
behavior.maxItemsInObjectGraph = maxItemsInObjectGraph;
}
}
}
}
}
}
}
}

View File

@@ -0,0 +1,344 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.ServiceModel;
using System.Collections.Generic;
public sealed class DispatchOperation
{
string action;
SynchronizedCollection<ICallContextInitializer> callContextInitializers;
SynchronizedCollection<FaultContractInfo> faultContractInfos;
IDispatchMessageFormatter formatter;
IDispatchFaultFormatter faultFormatter;
bool includeExceptionDetailInFaults;
ImpersonationOption impersonation;
IOperationInvoker invoker;
bool isTerminating;
bool isSessionOpenNotificationEnabled;
string name;
SynchronizedCollection<IParameterInspector> parameterInspectors;
DispatchRuntime parent;
bool releaseInstanceAfterCall;
bool releaseInstanceBeforeCall;
string replyAction;
bool transactionAutoComplete;
bool transactionRequired;
bool deserializeRequest = true;
bool serializeReply = true;
bool isOneWay;
bool autoDisposeParameters = true;
bool hasNoDisposableParameters;
bool isFaultFormatterSetExplicit = false;
bool isInsideTransactedReceiveScope = false;
public DispatchOperation(DispatchRuntime parent, string name, string action)
{
if (parent == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parent");
if (name == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("name");
this.parent = parent;
this.name = name;
this.action = action;
this.impersonation = OperationBehaviorAttribute.DefaultImpersonationOption;
this.callContextInitializers = parent.NewBehaviorCollection<ICallContextInitializer>();
this.faultContractInfos = parent.NewBehaviorCollection<FaultContractInfo>();
this.parameterInspectors = parent.NewBehaviorCollection<IParameterInspector>();
this.isOneWay = true;
}
public DispatchOperation(DispatchRuntime parent, string name, string action, string replyAction)
: this(parent, name, action)
{
this.replyAction = replyAction;
this.isOneWay = false;
}
public bool IsOneWay
{
get { return this.isOneWay; }
}
public string Action
{
get { return this.action; }
}
public SynchronizedCollection<ICallContextInitializer> CallContextInitializers
{
get { return this.callContextInitializers; }
}
public SynchronizedCollection<FaultContractInfo> FaultContractInfos
{
get { return this.faultContractInfos; }
}
public bool AutoDisposeParameters
{
get { return this.autoDisposeParameters; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.autoDisposeParameters = value;
}
}
}
public IDispatchMessageFormatter Formatter
{
get { return this.formatter; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.formatter = value;
}
}
}
internal IDispatchFaultFormatter FaultFormatter
{
get
{
if (this.faultFormatter == null)
{
this.faultFormatter = new DataContractSerializerFaultFormatter(this.faultContractInfos);
}
return this.faultFormatter;
}
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.faultFormatter = value;
this.isFaultFormatterSetExplicit = true;
}
}
}
internal bool IncludeExceptionDetailInFaults
{
get
{
return this.includeExceptionDetailInFaults;
}
set
{
this.includeExceptionDetailInFaults = value;
}
}
internal bool IsFaultFormatterSetExplicit
{
get
{
return this.isFaultFormatterSetExplicit;
}
}
public ImpersonationOption Impersonation
{
get { return this.impersonation; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.impersonation = value;
}
}
}
internal bool HasNoDisposableParameters
{
get { return this.hasNoDisposableParameters; }
set { this.hasNoDisposableParameters = value; }
}
internal IDispatchMessageFormatter InternalFormatter
{
get { return this.formatter; }
set { this.formatter = value; }
}
internal IOperationInvoker InternalInvoker
{
get { return this.invoker; }
set { this.invoker = value; }
}
public IOperationInvoker Invoker
{
get { return this.invoker; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.invoker = value;
}
}
}
public bool IsTerminating
{
get { return this.isTerminating; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.isTerminating = value;
}
}
}
internal bool IsSessionOpenNotificationEnabled
{
get { return this.isSessionOpenNotificationEnabled; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.isSessionOpenNotificationEnabled = value;
}
}
}
public string Name
{
get { return this.name; }
}
public SynchronizedCollection<IParameterInspector> ParameterInspectors
{
get { return this.parameterInspectors; }
}
public DispatchRuntime Parent
{
get { return this.parent; }
}
internal ReceiveContextAcknowledgementMode ReceiveContextAcknowledgementMode
{
get;
set;
}
internal bool BufferedReceiveEnabled
{
get { return this.parent.ChannelDispatcher.BufferedReceiveEnabled; }
set { this.parent.ChannelDispatcher.BufferedReceiveEnabled = value; }
}
public bool ReleaseInstanceAfterCall
{
get { return this.releaseInstanceAfterCall; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.releaseInstanceAfterCall = value;
}
}
}
public bool ReleaseInstanceBeforeCall
{
get { return this.releaseInstanceBeforeCall; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.releaseInstanceBeforeCall = value;
}
}
}
public string ReplyAction
{
get { return this.replyAction; }
}
public bool DeserializeRequest
{
get { return this.deserializeRequest; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.deserializeRequest = value;
}
}
}
public bool SerializeReply
{
get { return this.serializeReply; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.serializeReply = value;
}
}
}
public bool TransactionAutoComplete
{
get { return this.transactionAutoComplete; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.transactionAutoComplete = value;
}
}
}
public bool TransactionRequired
{
get { return this.transactionRequired; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.transactionRequired = value;
}
}
}
public bool IsInsideTransactedReceiveScope
{
get { return this.isInsideTransactedReceiveScope; }
set
{
lock (this.parent.ThisLock)
{
this.parent.InvalidateRuntime();
this.isInsideTransactedReceiveScope = value;
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More