Imported Upstream version 4.3.2.467

Former-commit-id: 9c2cb47f45fa221e661ab616387c9cda183f283d
This commit is contained in:
Xamarin Public Jenkins
2016-02-22 11:00:01 -05:00
parent f302175246
commit f3e3aab35a
4097 changed files with 122406 additions and 82300 deletions

View File

@@ -1,4 +1,3 @@
#if !FEATURE_PAL && !FEATURE_CORECLR
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
@@ -8,14 +7,23 @@
// <OWNER>AlfreMen</OWNER>
//
#if MONO
#undef FEATURE_COMINTEROP
#endif
using System;
using System.Security;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
#if FEATURE_COMINTEROP
using System.Runtime.InteropServices.WindowsRuntime;
using WFD = Windows.Foundation.Diagnostics;
#endif
namespace System.Threading.Tasks
{
@@ -23,39 +31,91 @@ namespace System.Threading.Tasks
[FriendAccessAllowed]
internal enum CausalityTraceLevel
{
#if FEATURE_COMINTEROP
Required = WFD.CausalityTraceLevel.Required,
Important = WFD.CausalityTraceLevel.Important,
Verbose = WFD.CausalityTraceLevel.Verbose
#else
Required,
Important,
Verbose
#endif
}
[FriendAccessAllowed]
internal enum AsyncCausalityStatus
{
#if FEATURE_COMINTEROP
Canceled = WFD.AsyncCausalityStatus.Canceled,
Completed = WFD.AsyncCausalityStatus.Completed,
Error = WFD.AsyncCausalityStatus.Error,
Started = WFD.AsyncCausalityStatus.Started
#else
Started,
Completed,
Canceled,
Error
#endif
}
internal enum CausalityRelation
{
#if FEATURE_COMINTEROP
AssignDelegate = WFD.CausalityRelation.AssignDelegate,
Join = WFD.CausalityRelation.Join,
Choice = WFD.CausalityRelation.Choice,
Cancel = WFD.CausalityRelation.Cancel,
Error = WFD.CausalityRelation.Error
#else
AssignDelegate,
Join,
Choice,
Cancel,
Error
#endif
}
internal enum CausalitySynchronousWork
{
#if FEATURE_COMINTEROP
CompletionNotification = WFD.CausalitySynchronousWork.CompletionNotification,
ProgressNotification = WFD.CausalitySynchronousWork.ProgressNotification,
Execution = WFD.CausalitySynchronousWork.Execution
#else
CompletionNotification,
ProgressNotification,
Execution
#endif
}
[FriendAccessAllowed]
internal static class AsyncCausalityTracer
{
static internal void EnableToETW(bool enabled)
{
#if !MONO
if (enabled)
f_LoggingOn |= Loggers.ETW;
else
f_LoggingOn &= ~Loggers.ETW;
#endif
}
[FriendAccessAllowed]
internal static bool LoggingOn
{
[FriendAccessAllowed]
get
{
#if FEATURE_COMINTEROP
return f_LoggingOn != 0;
#else
return false;
#endif
}
}
#if FEATURE_COMINTEROP
//s_PlatformId = {4B0171A6-F3D0-41A0-9B33-02550652B995}
private static readonly Guid s_PlatformId = new Guid(0x4B0171A6, 0xF3D0, 0x41A0, 0x9B, 0x33, 0x02, 0x55, 0x06, 0x52, 0xB9, 0x95);
@@ -65,33 +125,23 @@ namespace System.Threading.Tasks
//Lazy initialize the actual factory
private static WFD.IAsyncCausalityTracerStatics s_TracerFactory;
//We receive the actual value for these as a callback
private static bool f_LoggingOn; //assumes false by default
[FriendAccessAllowed]
internal static bool LoggingOn
{
[FriendAccessAllowed]
get
{
if (!f_FactoryInitialized)
FactoryInitialized();
return f_LoggingOn;
}
// The loggers that this Tracer knows about.
[Flags]
private enum Loggers : byte {
CausalityTracer = 1,
ETW = 2
}
private static bool f_FactoryInitialized; //assumes false by default
private static object _InitializationLock = new object();
//explicit cache
private static readonly Func<WFD.IAsyncCausalityTracerStatics> s_loadFactoryDelegate = LoadFactory;
//We receive the actual value for these as a callback
private static Loggers f_LoggingOn; //assumes false by default
// The precise static constructor will run first time somebody attempts to access this class
[SecuritySafeCritical]
private static WFD.IAsyncCausalityTracerStatics LoadFactory()
static AsyncCausalityTracer()
{
if (!Environment.IsWinRTSupported) return null;
if (!Environment.IsWinRTSupported) return;
//COM Class Id
string ClassId = "Windows.Foundation.Diagnostics.AsyncCausalityTracer";
@@ -99,84 +149,149 @@ namespace System.Threading.Tasks
Guid guid = new Guid(0x50850B26, 0x267E, 0x451B, 0xA8, 0x90, 0XAB, 0x6A, 0x37, 0x02, 0x45, 0xEE);
Object factory = null;
WFD.IAsyncCausalityTracerStatics validFactory = null;
try
{
int hresult = Microsoft.Win32.UnsafeNativeMethods.RoGetActivationFactory(ClassId, ref guid, out factory);
if (hresult < 0 || factory == null) return null; //This prevents having an exception thrown in case IAsyncCausalityTracerStatics isn't registered.
if (hresult < 0 || factory == null) return; //This prevents having an exception thrown in case IAsyncCausalityTracerStatics isn't registered.
validFactory = (WFD.IAsyncCausalityTracerStatics)factory;
s_TracerFactory = (WFD.IAsyncCausalityTracerStatics)factory;
EventRegistrationToken token = validFactory.add_TracingStatusChanged(new EventHandler<WFD.TracingStatusChangedEventArgs>(TracingStatusChangedHandler));
Contract.Assert(token != null, "EventRegistrationToken is null");
EventRegistrationToken token = s_TracerFactory.add_TracingStatusChanged(new EventHandler<WFD.TracingStatusChangedEventArgs>(TracingStatusChangedHandler));
Contract.Assert(token != default(EventRegistrationToken), "EventRegistrationToken is null");
}
catch (Exception)
catch (Exception ex)
{
// Although catching generic Exception is not recommended, this file is one exception
// since we don't want to propagate any kind of exception to the user since all we are
// doing here depends on internal state.
return null;
LogAndDisable(ex);
}
return validFactory;
}
private static bool FactoryInitialized()
{
return (LazyInitializer.EnsureInitialized(ref s_TracerFactory, ref f_FactoryInitialized, ref _InitializationLock, s_loadFactoryDelegate) != null);
}
[SecuritySafeCritical]
private static void TracingStatusChangedHandler(Object sender, WFD.TracingStatusChangedEventArgs args)
{
f_LoggingOn = args.Enabled;
if (args.Enabled)
f_LoggingOn |= Loggers.CausalityTracer;
else
f_LoggingOn &= ~Loggers.CausalityTracer;
}
#endif
//
// The TraceXXX methods should be called only if LoggingOn property returned true
//
[FriendAccessAllowed]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Tracking is slow path. Disable inlining for it.
internal static void TraceOperationCreation(CausalityTraceLevel traceLevel, int taskId, string operationName, ulong relatedContext)
{
if (LoggingOn)
#if FEATURE_COMINTEROP
try
{
s_TracerFactory.TraceOperationCreation((WFD.CausalityTraceLevel)traceLevel, s_CausalitySource, s_PlatformId, GetOperationId((uint)taskId), operationName, relatedContext);
if ((f_LoggingOn & Loggers.ETW) != 0)
TplEtwProvider.Log.TraceOperationBegin(taskId, operationName, (long) relatedContext);
if ((f_LoggingOn & Loggers.CausalityTracer) != 0)
s_TracerFactory.TraceOperationCreation((WFD.CausalityTraceLevel)traceLevel, s_CausalitySource, s_PlatformId, GetOperationId((uint)taskId), operationName, relatedContext);
}
catch(Exception ex)
{
//view function comment
LogAndDisable(ex);
}
#endif
}
[FriendAccessAllowed]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
internal static void TraceOperationCompletion(CausalityTraceLevel traceLevel, int taskId, AsyncCausalityStatus status)
{
if (LoggingOn)
#if FEATURE_COMINTEROP
try
{
s_TracerFactory.TraceOperationCompletion((WFD.CausalityTraceLevel)traceLevel, s_CausalitySource, s_PlatformId, GetOperationId((uint)taskId), (WFD.AsyncCausalityStatus)status);
if ((f_LoggingOn & Loggers.ETW) != 0)
TplEtwProvider.Log.TraceOperationEnd(taskId, status);
if ((f_LoggingOn & Loggers.CausalityTracer) != 0)
s_TracerFactory.TraceOperationCompletion((WFD.CausalityTraceLevel)traceLevel, s_CausalitySource, s_PlatformId, GetOperationId((uint)taskId), (WFD.AsyncCausalityStatus)status);
}
catch(Exception ex)
{
//view function comment
LogAndDisable(ex);
}
#endif
}
[MethodImplAttribute(MethodImplOptions.NoInlining)]
internal static void TraceOperationRelation(CausalityTraceLevel traceLevel, int taskId, CausalityRelation relation)
{
if (LoggingOn)
#if FEATURE_COMINTEROP
try
{
s_TracerFactory.TraceOperationRelation((WFD.CausalityTraceLevel)traceLevel, s_CausalitySource, s_PlatformId, GetOperationId((uint)taskId), (WFD.CausalityRelation)relation);
if ((f_LoggingOn & Loggers.ETW) != 0)
TplEtwProvider.Log.TraceOperationRelation(taskId, relation);
if ((f_LoggingOn & Loggers.CausalityTracer) != 0)
s_TracerFactory.TraceOperationRelation((WFD.CausalityTraceLevel)traceLevel, s_CausalitySource, s_PlatformId, GetOperationId((uint)taskId), (WFD.CausalityRelation)relation);
}
catch(Exception ex)
{
//view function comment
LogAndDisable(ex);
}
#endif
}
[MethodImplAttribute(MethodImplOptions.NoInlining)]
internal static void TraceSynchronousWorkStart(CausalityTraceLevel traceLevel, int taskId, CausalitySynchronousWork work)
{
if (LoggingOn)
#if FEATURE_COMINTEROP
try
{
s_TracerFactory.TraceSynchronousWorkStart((WFD.CausalityTraceLevel)traceLevel, s_CausalitySource, s_PlatformId, GetOperationId((uint)taskId), (WFD.CausalitySynchronousWork)work);
if ((f_LoggingOn & Loggers.ETW) != 0)
TplEtwProvider.Log.TraceSynchronousWorkBegin(taskId, work);
if ((f_LoggingOn & Loggers.CausalityTracer) != 0)
s_TracerFactory.TraceSynchronousWorkStart((WFD.CausalityTraceLevel)traceLevel, s_CausalitySource, s_PlatformId, GetOperationId((uint)taskId), (WFD.CausalitySynchronousWork)work);
}
catch(Exception ex)
{
//view function comment
LogAndDisable(ex);
}
#endif
}
[MethodImplAttribute(MethodImplOptions.NoInlining)]
internal static void TraceSynchronousWorkCompletion(CausalityTraceLevel traceLevel, CausalitySynchronousWork work)
{
if (LoggingOn)
#if FEATURE_COMINTEROP
try
{
s_TracerFactory.TraceSynchronousWorkCompletion((WFD.CausalityTraceLevel)traceLevel, s_CausalitySource, (WFD.CausalitySynchronousWork)work);
if ((f_LoggingOn & Loggers.ETW) != 0)
TplEtwProvider.Log.TraceSynchronousWorkEnd(work);
if ((f_LoggingOn & Loggers.CausalityTracer) != 0)
s_TracerFactory.TraceSynchronousWorkCompletion((WFD.CausalityTraceLevel)traceLevel, s_CausalitySource, (WFD.CausalitySynchronousWork)work);
}
catch(Exception ex)
{
//view function comment
LogAndDisable(ex);
}
#endif
}
#if FEATURE_COMINTEROP
//fix for 796185: leaking internal exceptions to customers,
//we should catch and log exceptions but never propagate them.
private static void LogAndDisable(Exception ex)
{
f_LoggingOn = 0;
Debugger.Log(0, "AsyncCausalityTracer", ex.ToString());
}
#endif
private static ulong GetOperationId(uint taskId)
{
return (((ulong)AppDomain.CurrentDomain.Id) << 32) + taskId;
@@ -184,5 +299,3 @@ namespace System.Threading.Tasks
}
}
#endif

View File

@@ -529,9 +529,6 @@ namespace System.Threading.Tasks
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public TResult Result
{
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
get { return IsWaitNotificationEnabledOrNotRanToCompletion ? GetResultCore(waitCompletionNotification: true) : m_result; }
}
@@ -544,9 +541,6 @@ namespace System.Threading.Tasks
/// </remarks>
internal TResult ResultOnSuccess
{
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
get
{
Contract.Assert(!IsWaitNotificationEnabledOrNotRanToCompletion,
@@ -695,15 +689,11 @@ namespace System.Threading.Tasks
Contract.Assert(false, "Invalid m_action in Task<TResult>");
}
#if !FEATURE_CORECLR || FEATURE_NETCORE
#region Await Support
/// <summary>Gets an awaiter used to await this <see cref="System.Threading.Tasks.Task{TResult}"/>.</summary>
/// <returns>An awaiter instance.</returns>
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
public new TaskAwaiter<TResult> GetAwaiter()
{
return new TaskAwaiter<TResult>(this);
@@ -714,16 +704,13 @@ namespace System.Threading.Tasks
/// true to attempt to marshal the continuation back to the original context captured; otherwise, false.
/// </param>
/// <returns>An object used to await this task.</returns>
#if !FEATURE_CORECLR
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
#endif
public new ConfiguredTaskAwaitable<TResult> ConfigureAwait(bool continueOnCapturedContext)
{
return new ConfiguredTaskAwaitable<TResult>(this, continueOnCapturedContext);
}
#endregion
#endif
#region Continuation methods
#region Action<Task<TResult>> continuations

View File

@@ -1 +1 @@
f17b2462e4086665f52411414a2a86cc9103e256
4168909f0dd17449e19e6aed3039bce3e82ce073

View File

@@ -1 +1 @@
612ac932e336859218839634e39d03f00ec318de
2b64b423d8e28a317807644569681db96f0c3521

View File

@@ -18,10 +18,10 @@ using System.Collections.Generic;
using System.Text;
using System.Security;
using System.Security.Permissions;
using System.Runtime.CompilerServices;
namespace System.Threading.Tasks
{
#if !FEATURE_PAL // PAL doesn't support eventing
using System.Diagnostics.Tracing;
/// <summary>Provides an event source for tracing TPL information.</summary>
@@ -31,6 +31,31 @@ namespace System.Threading.Tasks
LocalizationResources = "mscorlib")]
internal sealed class TplEtwProvider : EventSource
{
/// Used to determine if tasks should generate Activity IDs for themselves
internal bool TasksSetActivityIds; // This keyword is set
internal bool Debug;
private bool DebugActivityId;
/// <summary>
/// Get callbacks when the ETW sends us commands`
/// </summary>
protected override void OnEventCommand(EventCommandEventArgs command)
{
// To get the AsyncCausality events, we need to inform the AsyncCausalityTracer
if (command.Command == EventCommand.Enable)
AsyncCausalityTracer.EnableToETW(true);
else if (command.Command == EventCommand.Disable)
AsyncCausalityTracer.EnableToETW(false);
if (IsEnabled(EventLevel.Informational, Keywords.TasksFlowActivityIds))
ActivityTracker.Instance.Enable();
else
TasksSetActivityIds = IsEnabled(EventLevel.Informational, Keywords.TasksSetActivityIds);
Debug = IsEnabled(EventLevel.Informational, Keywords.Debug);
DebugActivityId = IsEnabled(EventLevel.Informational, Keywords.DebugActivityId);
}
/// <summary>
/// Defines the singleton instance for the TPL ETW provider.
/// The TPL Event provider GUID is {2e5dba47-a3d2-4d16-8ee0-6671ffdcd7b5}.
@@ -76,6 +101,10 @@ namespace System.Threading.Tasks
public const EventTask TaskScheduled = (EventTask)6;
/// <summary>An await task continuation is scheduled to execute.</summary>
public const EventTask AwaitTaskContinuationScheduled = (EventTask)7;
/// <summary>AsyncCausalityFunctionality.</summary>
public const EventTask TraceOperation = (EventTask)8;
public const EventTask TraceSynchronousWork = (EventTask)9;
}
public class Keywords // thisname is important for EventSource
@@ -94,6 +123,40 @@ namespace System.Threading.Tasks
/// Events associted with the higher level parallel APIs
/// </summary>
public const EventKeywords Parallel = (EventKeywords) 4;
/// <summary>
/// These are relatively verbose events that effectively just redirect
/// the windows AsyncCausalityTracer to ETW
/// </summary>
public const EventKeywords AsyncCausalityOperation = (EventKeywords) 8;
public const EventKeywords AsyncCausalityRelation = (EventKeywords) 0x10;
public const EventKeywords AsyncCausalitySynchronousWork = (EventKeywords) 0x20;
/// <summary>
/// Emit the stops as well as the schedule/start events
/// </summary>
public const EventKeywords TaskStops = (EventKeywords) 0x40;
/// <summary>
/// TasksFlowActivityIds indicate that activity ID flow from one task
/// to any task created by it.
/// </summary>
public const EventKeywords TasksFlowActivityIds = (EventKeywords) 0x80;
/// <summary>
/// TasksSetActivityIds will cause the task operations to set Activity Ids
/// This option is incompatible with TasksFlowActivityIds flow is ignored
/// if that keyword is set. This option is likley to be removed in the future
/// </summary>
public const EventKeywords TasksSetActivityIds = (EventKeywords) 0x10000;
/// <summary>
/// Relatively Verbose logging meant for debugging the Task library itself. Will probably be removed in the future
/// </summary>
public const EventKeywords Debug = (EventKeywords) 0x20000;
/// <summary>
/// Relatively Verbose logging meant for debugging the Task library itself. Will probably be removed in the future
/// </summary>
public const EventKeywords DebugActivityId = (EventKeywords) 0x40000;
}
/// <summary>Enabled for all keywords.</summary>
@@ -129,6 +192,18 @@ namespace System.Threading.Tasks
private const int TASKWAITEND_ID = 11;
/// <summary>A continuation of a task is scheduled.</summary>
private const int AWAITTASKCONTINUATIONSCHEDULED_ID = 12;
/// <summary>A continuation of a taskWaitEnd is complete </summary>
private const int TASKWAITCONTINUATIONCOMPLETE_ID = 13;
/// <summary>A continuation of a taskWaitEnd is complete </summary>
private const int TASKWAITCONTINUATIONSTARTED_ID = 19;
private const int TRACEOPERATIONSTART_ID = 14;
private const int TRACEOPERATIONSTOP_ID = 15;
private const int TRACEOPERATIONRELATION_ID = 16;
private const int TRACESYNCHRONOUSWORKSTART_ID = 17;
private const int TRACESYNCHRONOUSWORKSTOP_ID = 18;
//-----------------------------------------------------------------------------------
//
// Parallel Events
@@ -145,7 +220,8 @@ namespace System.Threading.Tasks
/// <param name="InclusiveFrom">The lower bound of the loop.</param>
/// <param name="ExclusiveTo">The upper bound of the loop.</param>
[SecuritySafeCritical]
[Event(PARALLELLOOPBEGIN_ID, Level = EventLevel.Informational, Task = TplEtwProvider.Tasks.Loop, Opcode = EventOpcode.Start)]
[Event(PARALLELLOOPBEGIN_ID, Level = EventLevel.Informational, ActivityOptions=EventActivityOptions.Recursive,
Task = TplEtwProvider.Tasks.Loop, Opcode = EventOpcode.Start)]
public void ParallelLoopBegin(
int OriginatingTaskSchedulerID, int OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
int ForkJoinContextID, ForkJoinOperationType OperationType, // PFX_FORKJOIN_COMMON_EVENT_HEADER
@@ -226,7 +302,8 @@ namespace System.Threading.Tasks
/// <param name="OperationType">The kind of fork/join operation.</param>
/// <param name="ActionCount">The number of actions being invoked.</param>
[SecuritySafeCritical]
[Event(PARALLELINVOKEBEGIN_ID, Level = EventLevel.Informational, Task = TplEtwProvider.Tasks.Invoke, Opcode = EventOpcode.Start)]
[Event(PARALLELINVOKEBEGIN_ID, Level = EventLevel.Informational, ActivityOptions=EventActivityOptions.Recursive,
Task = TplEtwProvider.Tasks.Invoke, Opcode = EventOpcode.Start)]
public void ParallelInvokeBegin(
int OriginatingTaskSchedulerID, int OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
int ForkJoinContextID, ForkJoinOperationType OperationType, // PFX_FORKJOIN_COMMON_EVENT_HEADER
@@ -286,7 +363,8 @@ namespace System.Threading.Tasks
/// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
/// <param name="OriginatingTaskID">The task ID.</param>
/// <param name="ForkJoinContextID">The invoke ID.</param>
[Event(PARALLELFORK_ID, Level = EventLevel.Verbose, Task = TplEtwProvider.Tasks.ForkJoin, Opcode = EventOpcode.Start)]
[Event(PARALLELFORK_ID, Level = EventLevel.Verbose, ActivityOptions=EventActivityOptions.Recursive,
Task = TplEtwProvider.Tasks.ForkJoin, Opcode = EventOpcode.Start)]
public void ParallelFork(
int OriginatingTaskSchedulerID, int OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
int ForkJoinContextID)
@@ -338,11 +416,11 @@ namespace System.Threading.Tasks
/// <param name="CreatingTaskID">The task ID</param>
/// <param name="TaskCreationOptions">The options used to create the task.</param>
[SecuritySafeCritical]
[Event(TASKSCHEDULED_ID, Task = Tasks.TaskScheduled, Opcode = EventOpcode.Send,
[Event(TASKSCHEDULED_ID, Task = Tasks.TaskScheduled, Version=1, Opcode = EventOpcode.Send,
Level = EventLevel.Informational, Keywords = Keywords.TaskTransfer|Keywords.Tasks)]
public void TaskScheduled(
int OriginatingTaskSchedulerID, int OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
int TaskID, int CreatingTaskID, int TaskCreationOptions)
int TaskID, int CreatingTaskID, int TaskCreationOptions, int appDomain)
{
// IsEnabled() call is an inlined quick check that makes this very fast when provider is off
if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.TaskTransfer|Keywords.Tasks))
@@ -360,8 +438,13 @@ namespace System.Threading.Tasks
eventPayload[3].DataPointer = ((IntPtr) (&CreatingTaskID));
eventPayload[4].Size = sizeof(int);
eventPayload[4].DataPointer = ((IntPtr) (&TaskCreationOptions));
Guid childActivityId = CreateGuidForTaskID(TaskID);
WriteEventWithRelatedActivityIdCore(TASKSCHEDULED_ID, &childActivityId, 5, eventPayload);
if (TasksSetActivityIds)
{
Guid childActivityId = CreateGuidForTaskID(TaskID);
WriteEventWithRelatedActivityIdCore(TASKSCHEDULED_ID, &childActivityId, 5, eventPayload);
}
else
WriteEventCore(TASKSCHEDULED_ID, 5, eventPayload);
}
}
}
@@ -374,7 +457,7 @@ namespace System.Threading.Tasks
/// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
/// <param name="OriginatingTaskID">The task ID.</param>
/// <param name="TaskID">The task ID.</param>
[Event(TASKSTARTED_ID, Task = TplEtwProvider.Tasks.TaskExecute, Opcode = EventOpcode.Start,
[Event(TASKSTARTED_ID,
Level = EventLevel.Informational, Keywords = Keywords.Tasks)]
public void TaskStarted(
int OriginatingTaskSchedulerID, int OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
@@ -394,8 +477,8 @@ namespace System.Threading.Tasks
/// <param name="TaskID">The task ID.</param>
/// <param name="IsExceptional">Whether the task completed due to an error.</param>
[SecuritySafeCritical]
[Event(TASKCOMPLETED_ID, Version=1, Task = TplEtwProvider.Tasks.TaskExecute, Opcode = EventOpcode.Stop,
Level = EventLevel.Informational, Keywords = Keywords.Tasks)]
[Event(TASKCOMPLETED_ID, Version=1,
Level = EventLevel.Informational, Keywords = Keywords.TaskStops)]
public void TaskCompleted(
int OriginatingTaskSchedulerID, int OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
int TaskID, bool IsExceptional)
@@ -420,7 +503,7 @@ namespace System.Threading.Tasks
}
#endregion
#region TaskWaitBegin
#region TaskWaitBegin
/// <summary>
/// Fired when starting to wait for a taks's completion explicitly or implicitly.
/// </summary>
@@ -428,18 +511,21 @@ namespace System.Threading.Tasks
/// <param name="OriginatingTaskID">The task ID.</param>
/// <param name="TaskID">The task ID.</param>
/// <param name="Behavior">Configured behavior for the wait.</param>
/// <param name="ContinueWithTaskID">If known, if 'TaskID' has a 'continueWith' task, mention give its ID here.
/// 0 means unknown. This allows better visualization of the common sequential chaining case.</param>
/// </summary>
[SecuritySafeCritical]
[Event(TASKWAITBEGIN_ID, Version=1, Task = TplEtwProvider.Tasks.TaskWait, Opcode = EventOpcode.Send,
[Event(TASKWAITBEGIN_ID, Version=3, Task = TplEtwProvider.Tasks.TaskWait, Opcode = EventOpcode.Send,
Level = EventLevel.Informational, Keywords = Keywords.TaskTransfer|Keywords.Tasks)]
public void TaskWaitBegin(
int OriginatingTaskSchedulerID, int OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
int TaskID, TaskWaitBehavior Behavior)
int TaskID, TaskWaitBehavior Behavior, int ContinueWithTaskID, int appDomain)
{
if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.TaskTransfer|Keywords.Tasks))
{
unsafe
{
EventData* eventPayload = stackalloc EventData[4];
EventData* eventPayload = stackalloc EventData[5];
eventPayload[0].Size = sizeof(int);
eventPayload[0].DataPointer = ((IntPtr)(&OriginatingTaskSchedulerID));
eventPayload[1].Size = sizeof(int);
@@ -448,21 +534,27 @@ namespace System.Threading.Tasks
eventPayload[2].DataPointer = ((IntPtr)(&TaskID));
eventPayload[3].Size = sizeof(int);
eventPayload[3].DataPointer = ((IntPtr)(&Behavior));
Guid childActivityId = CreateGuidForTaskID(TaskID);
WriteEventWithRelatedActivityIdCore(TASKWAITBEGIN_ID, &childActivityId, 4, eventPayload);
eventPayload[4].Size = sizeof(int);
eventPayload[4].DataPointer = ((IntPtr)(&ContinueWithTaskID));
if (TasksSetActivityIds)
{
Guid childActivityId = CreateGuidForTaskID(TaskID);
WriteEventWithRelatedActivityIdCore(TASKWAITBEGIN_ID, &childActivityId, 5, eventPayload);
}
else
WriteEventCore(TASKWAITBEGIN_ID, 5, eventPayload);
}
}
}
#endregion
#region TaskWaitEnd
/// <summary>
/// Fired when the wait for a tasks completion returns.
/// </summary>
/// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
/// <param name="OriginatingTaskID">The task ID.</param>
/// <param name="TaskID">The task ID.</param>
[Event(TASKWAITEND_ID, Task = TplEtwProvider.Tasks.TaskWait, Opcode = EventOpcode.Stop,
[Event(TASKWAITEND_ID,
Level = EventLevel.Verbose, Keywords = Keywords.Tasks)]
public void TaskWaitEnd(
int OriginatingTaskSchedulerID, int OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
@@ -473,6 +565,36 @@ namespace System.Threading.Tasks
WriteEvent(TASKWAITEND_ID, OriginatingTaskSchedulerID, OriginatingTaskID, TaskID);
}
/// <summary>
/// Fired when the the work (method) associated with a TaskWaitEnd completes
/// </summary>
/// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
/// <param name="OriginatingTaskID">The task ID.</param>
/// <param name="TaskID">The task ID.</param>
[Event(TASKWAITCONTINUATIONCOMPLETE_ID,
Level = EventLevel.Verbose, Keywords = Keywords.TaskStops)]
public void TaskWaitContinuationComplete(int TaskID)
{
// Log an event if indicated.
if (IsEnabled() && IsEnabled(EventLevel.Verbose, Keywords.Tasks))
WriteEvent(TASKWAITCONTINUATIONCOMPLETE_ID, TaskID);
}
/// <summary>
/// Fired when the the work (method) associated with a TaskWaitEnd completes
/// </summary>
/// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
/// <param name="OriginatingTaskID">The task ID.</param>
/// <param name="TaskID">The task ID.</param>
[Event(TASKWAITCONTINUATIONSTARTED_ID,
Level = EventLevel.Verbose, Keywords = Keywords.TaskStops)]
public void TaskWaitContinuationStarted(int TaskID)
{
// Log an event if indicated.
if (IsEnabled() && IsEnabled(EventLevel.Verbose, Keywords.Tasks))
WriteEvent(TASKWAITCONTINUATIONSTARTED_ID, TaskID);
}
/// <summary>
/// Fired when the an asynchronous continuation for a task is scheduled
/// </summary>
@@ -484,7 +606,7 @@ namespace System.Threading.Tasks
Level = EventLevel.Informational, Keywords = Keywords.TaskTransfer|Keywords.Tasks)]
public void AwaitTaskContinuationScheduled(
int OriginatingTaskSchedulerID, int OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
int continuationId)
int ContinuwWithTaskId)
{
if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.TaskTransfer|Keywords.Tasks))
{
@@ -496,13 +618,131 @@ namespace System.Threading.Tasks
eventPayload[1].Size = sizeof(int);
eventPayload[1].DataPointer = ((IntPtr) (&OriginatingTaskID));
eventPayload[2].Size = sizeof(int);
eventPayload[2].DataPointer = ((IntPtr) (&continuationId));
Guid continuationActivityId = CreateGuidForTaskID(continuationId);
WriteEventWithRelatedActivityIdCore(AWAITTASKCONTINUATIONSCHEDULED_ID, &continuationActivityId, 3, eventPayload);
eventPayload[2].DataPointer = ((IntPtr) (&ContinuwWithTaskId));
if (TasksSetActivityIds)
{
Guid continuationActivityId = CreateGuidForTaskID(ContinuwWithTaskId);
WriteEventWithRelatedActivityIdCore(AWAITTASKCONTINUATIONSCHEDULED_ID, &continuationActivityId, 3, eventPayload);
}
else
WriteEventCore(AWAITTASKCONTINUATIONSCHEDULED_ID, 3, eventPayload);
}
}
}
[SecuritySafeCritical]
[Event(TRACEOPERATIONSTART_ID, Version=1,
Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalityOperation)]
public void TraceOperationBegin(int TaskID, string OperationName, long RelatedContext)
{
if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.AsyncCausalityOperation))
{
unsafe
{
fixed(char* operationNamePtr = OperationName)
{
EventData* eventPayload = stackalloc EventData[3];
eventPayload[0].Size = sizeof(int);
eventPayload[0].DataPointer = ((IntPtr) (&TaskID));
eventPayload[1].Size = ((OperationName.Length + 1) * 2);
eventPayload[1].DataPointer = ((IntPtr) operationNamePtr);
eventPayload[2].Size = sizeof(long);
eventPayload[2].DataPointer = ((IntPtr) (&RelatedContext));
WriteEventCore(TRACEOPERATIONSTART_ID, 3, eventPayload);
}
}
}
}
[SecuritySafeCritical]
[Event(TRACEOPERATIONRELATION_ID, Version=1,
Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalityRelation)]
public void TraceOperationRelation(int TaskID, CausalityRelation Relation)
{
if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.AsyncCausalityRelation))
WriteEvent(TRACEOPERATIONRELATION_ID, TaskID,(int) Relation); // optmized overload for this exists
}
[SecuritySafeCritical]
[Event(TRACEOPERATIONSTOP_ID, Version=1,
Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalityOperation)]
public void TraceOperationEnd(int TaskID, AsyncCausalityStatus Status)
{
if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.AsyncCausalityOperation))
WriteEvent(TRACEOPERATIONSTOP_ID, TaskID,(int) Status); // optmized overload for this exists
}
[SecuritySafeCritical]
[Event(TRACESYNCHRONOUSWORKSTART_ID, Version=1,
Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalitySynchronousWork)]
public void TraceSynchronousWorkBegin(int TaskID, CausalitySynchronousWork Work)
{
if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.AsyncCausalitySynchronousWork))
WriteEvent(TRACESYNCHRONOUSWORKSTART_ID, TaskID,(int) Work); // optmized overload for this exists
}
[SecuritySafeCritical]
[Event(TRACESYNCHRONOUSWORKSTOP_ID, Version=1,
Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalitySynchronousWork)]
public void TraceSynchronousWorkEnd(CausalitySynchronousWork Work)
{
if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.AsyncCausalitySynchronousWork))
{
unsafe
{
EventData* eventPayload = stackalloc EventData[1];
eventPayload[0].Size = sizeof(int);
eventPayload[0].DataPointer = ((IntPtr) (&Work));
WriteEventCore(TRACESYNCHRONOUSWORKSTOP_ID, 1, eventPayload);
}
}
}
[NonEvent, System.Security.SecuritySafeCritical]
unsafe public void RunningContinuation(int TaskID, object Object) { RunningContinuation(TaskID, (long) *((void**) JitHelpers.UnsafeCastToStackPointer(ref Object))); }
[Event(20, Keywords = Keywords.Debug)]
private void RunningContinuation(int TaskID, long Object)
{
if (Debug)
WriteEvent(20, TaskID, Object);
}
[NonEvent, System.Security.SecuritySafeCritical]
unsafe public void RunningContinuationList(int TaskID, int Index, object Object) { RunningContinuationList(TaskID, Index, (long) *((void**) JitHelpers.UnsafeCastToStackPointer(ref Object))); }
[Event(21, Keywords = Keywords.Debug)]
public void RunningContinuationList(int TaskID, int Index, long Object)
{
if (Debug)
WriteEvent(21, TaskID, Index, Object);
}
[Event(22, Keywords = Keywords.Debug)]
public void DebugMessage(string Message) { WriteEvent(22, Message); }
[Event(23, Keywords = Keywords.Debug)]
public void DebugFacilityMessage(string Facility, string Message) { WriteEvent(23, Facility, Message); }
[Event(24, Keywords = Keywords.Debug)]
public void DebugFacilityMessage1(string Facility, string Message, string Value1) { WriteEvent(24, Facility, Message, Value1); }
[Event(25, Keywords = Keywords.DebugActivityId)]
public void SetActivityId(Guid NewId)
{
if (DebugActivityId)
WriteEvent(25, NewId);
}
[Event(26, Keywords = Keywords.Debug)]
public void NewID(int TaskID)
{
if (Debug)
WriteEvent(26, TaskID);
}
/// <summary>
/// Activity IDs are GUIDS but task IDS are integers (and are not unique across appdomains
/// This routine creates a process wide unique GUID given a task ID
@@ -515,12 +755,10 @@ namespace System.Threading.Tasks
// These were generated by CreateGuid, and are reasonably random (and thus unlikley to collide
uint pid = EventSource.s_currentPid;
int appDomainID = System.Threading.Thread.GetDomainID();
return new Guid(taskID,
(short) appDomainID , (short) (appDomainID >> 16),
(byte)pid, (byte)(pid >> 8), (byte)(pid >> 16), (byte)(pid >> 24),
0xff, 0xdc, 0xd7, 0xb5);
return new Guid(taskID,
(short) appDomainID , (short) (appDomainID >> 16),
(byte)pid, (byte)(pid >> 8), (byte)(pid >> 16), (byte)(pid >> 24),
0xff, 0xdc, 0xd7, 0xb5);
}
#endregion
}
#endif // !FEATURE_PAL
}

View File

@@ -1 +1 @@
75e440fcf3ba1400690187ba89cc60e368eb072c
1e3f9293f7c31efdabd588b569ba8cd587752795

View File

@@ -343,9 +343,9 @@ namespace System.Threading.Tasks
}
// Enables a token to be stored into the canceled task
internal bool TrySetCanceled(CancellationToken tokenToRecord)
public bool TrySetCanceled(CancellationToken cancellationToken)
{
bool rval = m_task.TrySetCanceled(tokenToRecord);
bool rval = m_task.TrySetCanceled(cancellationToken);
if (!rval && !m_task.IsCompleted) SpinUntilCompleted();
return rval;
}

View File

@@ -307,7 +307,6 @@ namespace System.Threading.Tasks
m_task = task;
m_options = options;
m_taskScheduler = scheduler;
#if !FEATURE_PAL && !FEATURE_CORECLR
if (AsyncCausalityTracer.LoggingOn)
AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, m_task.Id, "Task.ContinueWith: " + ((Delegate)task.m_action).Method.Name, 0);
@@ -315,7 +314,6 @@ namespace System.Threading.Tasks
{
Task.AddToActiveTasks(m_task);
}
#endif
}
/// <summary>Invokes the continuation for the target completion task.</summary>
@@ -340,8 +338,6 @@ namespace System.Threading.Tasks
Task continuationTask = m_task;
if (isRightKind)
{
#if !FEATURE_PAL && !FEATURE_CORECLR
//If the task was cancel before running (e.g a ContinueWhenAll with a cancelled caancelation token)
//we will still flow it to ScheduleAndStart() were it will check the status before running
//We check here to avoid faulty logs that contain a join event to an operation that was already set as completed.
@@ -350,7 +346,6 @@ namespace System.Threading.Tasks
// Log now that we are sure that this continuation is being ran
AsyncCausalityTracer.TraceOperationRelation(CausalityTraceLevel.Important, continuationTask.Id, CausalityRelation.AssignDelegate);
}
#endif
continuationTask.m_taskScheduler = m_taskScheduler;
// Either run directly or just queue it up for execution, depending
@@ -426,7 +421,7 @@ namespace System.Threading.Tasks
// Otherwise, Post the action back to the SynchronizationContext.
else
{
#if !FEATURE_PAL && !FEATURE_CORECLR // PAL and CoreClr don't support eventing
#if !MONO
TplEtwProvider etwLog = TplEtwProvider.Log;
if (etwLog.IsEnabled())
{
@@ -445,21 +440,19 @@ namespace System.Threading.Tasks
private static void PostAction(object state)
{
var c = (SynchronizationContextAwaitTaskContinuation)state;
#if !FEATURE_PAL && !FEATURE_CORECLR // PAL and CoreClr don't support eventing
#if !MONO
TplEtwProvider etwLog = TplEtwProvider.Log;
if (etwLog.IsEnabled() && c.m_continuationId != 0)
if (etwLog.TasksSetActivityIds && c.m_continuationId != 0)
{
c.m_syncContext.Post(s_postCallback, GetActionLogDelegate(c.m_continuationId, c.m_action));
}
else
#endif
#endif
{
c.m_syncContext.Post(s_postCallback, c.m_action); // s_postCallback is manually cached, as the compiler won't in a SecurityCritical method
}
}
#if !FEATURE_PAL && !FEATURE_CORECLR // PAL and CoreClr don't support eventing
#if !MONO
private static Action GetActionLogDelegate(int continuationId, Action action)
{
return () =>
@@ -472,15 +465,12 @@ namespace System.Threading.Tasks
};
}
#endif
/// <summary>Gets a cached delegate for the PostAction method.</summary>
/// <returns>
/// A delegate for PostAction, which expects a SynchronizationContextAwaitTaskContinuation
/// to be passed as state.
/// </returns>
#if !FEATURE_CORECLR
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
[SecurityCritical]
private static ContextCallback GetPostActionCallback()
{
@@ -560,9 +550,7 @@ namespace System.Threading.Tasks
/// <summary>The action to invoke.</summary>
protected readonly Action m_action;
#if !FEATURE_PAL && !FEATURE_CORECLR // PAL and CoreClr don't support eventing
protected int m_continuationId;
#endif
/// <summary>Initializes the continuation.</summary>
/// <param name="action">The action to invoke. Must not be null.</param>
@@ -630,7 +618,7 @@ namespace System.Threading.Tasks
}
else
{
#if !FEATURE_PAL && !FEATURE_CORECLR // PAL and CoreClr don't support eventing
#if !MONO
TplEtwProvider etwLog = TplEtwProvider.Log;
if (etwLog.IsEnabled())
{
@@ -679,44 +667,44 @@ namespace System.Threading.Tasks
[SecurityCritical]
void ExecuteWorkItemHelper()
{
#if !FEATURE_PAL && !FEATURE_CORECLR // PAL and CoreClr don't support eventing
#if !MONO
var etwLog = TplEtwProvider.Log;
Guid savedActivityId = Guid.Empty;
if (etwLog.IsEnabled() && m_continuationId != 0)
if (etwLog.TasksSetActivityIds && m_continuationId != 0)
{
Guid activityId = TplEtwProvider.CreateGuidForTaskID(m_continuationId);
System.Diagnostics.Tracing.EventSource.SetCurrentThreadActivityId(activityId, out savedActivityId);
}
#endif
try
{
#endif
// We're not inside of a task, so t_currentTask doesn't need to be specially maintained.
// We're on a thread pool thread with no higher-level callers, so exceptions can just propagate.
// We're not inside of a task, so t_currentTask doesn't need to be specially maintained.
// We're on a thread pool thread with no higher-level callers, so exceptions can just propagate.
// If there's no execution context, just invoke the delegate.
if (m_capturedContext == null)
{
m_action();
}
// If there is an execution context, get the cached delegate and run the action under the context.
else
{
try
// If there's no execution context, just invoke the delegate.
if (m_capturedContext == null)
{
ExecutionContext.Run(m_capturedContext, GetInvokeActionCallback(), m_action, true);
m_action();
}
// If there is an execution context, get the cached delegate and run the action under the context.
else
{
try
{
ExecutionContext.Run(m_capturedContext, GetInvokeActionCallback(), m_action, true);
}
finally { m_capturedContext.Dispose(); }
}
finally { m_capturedContext.Dispose(); }
}
#if !FEATURE_PAL && !FEATURE_CORECLR // PAL and CoreClr don't support eventing
}
finally
{
if (etwLog.IsEnabled() && m_continuationId != 0)
#if !MONO
if (etwLog.TasksSetActivityIds && m_continuationId != 0)
{
System.Diagnostics.Tracing.EventSource.SetCurrentThreadActivityId(savedActivityId);
}
}
#endif
}
}
[SecurityCritical]
@@ -724,9 +712,9 @@ namespace System.Threading.Tasks
{
// inline the fast path
if (m_capturedContext == null
#if !FEATURE_PAL && !FEATURE_CORECLR // PAL and CoreClr don't support eventing
&& !TplEtwProvider.Log.IsEnabled()
#endif
#if !MONO
&& !TplEtwProvider.Log.IsEnabled()
#endif
)
{
m_action();
@@ -752,9 +740,7 @@ namespace System.Threading.Tasks
[SecurityCritical]
private static void InvokeAction(object state) { ((Action)state)(); }
#if !FEATURE_CORECLR
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
[SecurityCritical]
protected static ContextCallback GetInvokeActionCallback()
{
@@ -850,8 +836,7 @@ namespace System.Threading.Tasks
internal static void UnsafeScheduleAction(Action action, Task task)
{
AwaitTaskContinuation atc = new AwaitTaskContinuation(action, flowExecutionContext: false);
#if !FEATURE_PAL && !FEATURE_CORECLR // PAL and CoreClr don't support eventing
#if !MONO
var etwLog = TplEtwProvider.Log;
if (etwLog.IsEnabled() && task != null)
{
@@ -859,7 +844,6 @@ namespace System.Threading.Tasks
etwLog.AwaitTaskContinuationScheduled((task.ExecutingTaskScheduler ?? TaskScheduler.Default).Id, task.Id, atc.m_continuationId);
}
#endif
ThreadPool.UnsafeQueueCustomWorkItem(atc, forceGlobal: false);
}
@@ -890,11 +874,7 @@ namespace System.Threading.Tasks
internal override Delegate[] GetDelegateContinuationsForDebugger()
{
Contract.Assert(m_action != null);
#if !FEATURE_CORECLR || FEATURE_NETCORE
return new Delegate[] { AsyncMethodBuilderCore.TryGetStateMachineForDebugger(m_action) };
#else
return new Delegate[] { m_action };
#endif
}
}

View File

@@ -77,6 +77,7 @@ namespace System.Threading.Tasks
private static void EnsureADUnloadCallbackRegistered()
{
#if MONO_FEATURE_MULTIPLE_APPDOMAINS
if (s_adUnloadEventHandler == null &&
Interlocked.CompareExchange( ref s_adUnloadEventHandler,
AppDomainUnloadCallback,
@@ -84,6 +85,7 @@ namespace System.Threading.Tasks
{
AppDomain.CurrentDomain.DomainUnload += s_adUnloadEventHandler;
}
#endif
}
private static void AppDomainUnloadCallback(object sender, EventArgs e)

View File

@@ -1 +1 @@
60e5a447ad78dc121f813b292c8e5dd068691d7d
3c8e798e0311370d8c30a814ea22dc3942748e43

View File

@@ -215,9 +215,7 @@ namespace System.Threading.Tasks
bool bInlined = false;
try
{
#if !FEATURE_PAL && !FEATURE_CORECLR
task.FireTaskScheduledIfNeeded(this);
#endif
bInlined = TryExecuteTaskInline(task, taskWasPreviouslyQueued);
}
finally
@@ -272,9 +270,8 @@ namespace System.Threading.Tasks
{
Contract.Requires(task != null);
#if !FEATURE_PAL && !FEATURE_CORECLR
task.FireTaskScheduledIfNeeded(this);
#endif
this.QueueTask(task);
}
@@ -362,9 +359,7 @@ namespace System.Threading.Tasks
{
Task currentTask = Task.InternalCurrent;
return ( (currentTask != null)
#if !FEATURE_CORECLR || FEATURE_NETCORE
&& ((currentTask.CreationOptions & TaskCreationOptions.HideScheduler) == 0)
#endif
) ? currentTask.ExecutingTaskScheduler : null;
}
}