Skip to content
This repository was archived by the owner on Nov 1, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\ThreadStateException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\Timeout.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\TimeoutHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\Timer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\WaitHandleCannotBeOpenedException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\ThreadStaticAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\ThrowHelper.cs" />
Expand Down
8 changes: 4 additions & 4 deletions src/System.Private.CoreLib/shared/System/IO/MemoryStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ public override Task<int> ReadAsync(byte[] buffer, int offset, int count, Cancel
}
catch (OperationCanceledException oce)
{
return Task.FromCancellation<int>(oce);
return Task.FromCanceled<int>(oce);
}
catch (Exception exception)
{
Expand Down Expand Up @@ -450,7 +450,7 @@ public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken
}
catch (OperationCanceledException oce)
{
return new ValueTask<int>(Task.FromCancellation<int>(oce));
return new ValueTask<int>(Task.FromCanceled<int>(oce));
}
catch (Exception exception)
{
Expand Down Expand Up @@ -739,7 +739,7 @@ public override Task WriteAsync(byte[] buffer, int offset, int count, Cancellati
}
catch (OperationCanceledException oce)
{
return Task.FromCancellation<VoidTaskResult>(oce);
return Task.FromCanceled(oce);
}
catch (Exception exception)
{
Expand Down Expand Up @@ -770,7 +770,7 @@ public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationTo
}
catch (OperationCanceledException oce)
{
return new ValueTask(Task.FromCancellation<VoidTaskResult>(oce));
return new ValueTask(Task.FromCanceled(oce));
}
catch (Exception exception)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ public struct AsyncTaskMethodBuilder
#if PROJECTN
private static readonly Task<VoidTaskResult> s_cachedCompleted = AsyncTaskCache.CreateCacheableTask<VoidTaskResult>(default(VoidTaskResult));
#else
private readonly static Task<VoidTaskResult> s_cachedCompleted = AsyncTaskMethodBuilder<VoidTaskResult>.s_defaultResultTask;
private static readonly Task<VoidTaskResult> s_cachedCompleted = AsyncTaskMethodBuilder<VoidTaskResult>.s_defaultResultTask;
#endif

/// <summary>The generic builder object to which this non-generic instance delegates.</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,7 @@ public static AsyncValueTaskMethodBuilder Create() =>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine =>
// will provide the right ExecutionContext semantics
#if netstandard
_methodBuilder.Start(ref stateMachine);
#else
AsyncMethodBuilderCore.Start(ref stateMachine);
#endif

/// <summary>Associates the builder with the specified state machine.</summary>
/// <param name="stateMachine">The state machine instance to associate with the builder.</param>
Expand Down Expand Up @@ -143,11 +139,7 @@ public static AsyncValueTaskMethodBuilder<TResult> Create() =>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine =>
// will provide the right ExecutionContext semantics
#if netstandard
_methodBuilder.Start(ref stateMachine);
#else
AsyncMethodBuilderCore.Start(ref stateMachine);
#endif

/// <summary>Associates the builder with the specified state machine.</summary>
/// <param name="stateMachine">The state machine instance to associate with the builder.</param>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,10 @@ public bool Set()
throw Win32Marshal.GetExceptionForLastWin32Error();
return res;
}

internal static bool Set(SafeWaitHandle waitHandle)
{
return Interop.Kernel32.SetEvent(waitHandle);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ public void Complete()
public Task Completion
{
// ValueLock not needed, but it's ok if it's held
get { return EnsureCompletionStateInitialized().Task; }
get { return EnsureCompletionStateInitialized(); }
}

/// <summary>Gets the lazily-initialized completion state.</summary>
Expand Down Expand Up @@ -214,12 +214,12 @@ private void CompleteTaskAsync()
ThreadPool.QueueUserWorkItem(state =>
{
var localThis = (ConcurrentExclusiveSchedulerPair)state;
Debug.Assert(!localThis.m_completionState.Task.IsCompleted, "Completion should only happen once.");
Debug.Assert(!localThis.m_completionState.IsCompleted, "Completion should only happen once.");

List<Exception> exceptions = localThis.m_completionState.m_exceptions;
bool success = (exceptions != null && exceptions.Count > 0) ?
localThis.m_completionState.TrySetException(exceptions) :
localThis.m_completionState.TrySetResult(default);
localThis.m_completionState.TrySetResult();
Debug.Assert(success, "Expected to complete completion task.");

localThis.m_threadProcessingMode.Dispose();
Expand Down Expand Up @@ -479,7 +479,7 @@ private void ProcessConcurrentTasks()
/// the Completion.
/// </summary>
[SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")]
private sealed class CompletionState : TaskCompletionSource<VoidTaskResult>
private sealed class CompletionState : Task
{
/// <summary>Whether the scheduler has had completion requested.</summary>
/// <remarks>This variable is not volatile, so to gurantee safe reading reads, Volatile.Read is used in TryExecuteTaskInline.</remarks>
Expand Down Expand Up @@ -741,7 +741,7 @@ private ProcessingMode ModeForDebugger
get
{
// If our completion task is done, so are we.
if (m_completionState != null && m_completionState.Task.IsCompleted) return ProcessingMode.Completed;
if (m_completionState != null && m_completionState.IsCompleted) return ProcessingMode.Completed;

// Otherwise, summarize our current state.
var mode = ProcessingMode.NotCurrentlyProcessing;
Expand Down
95 changes: 4 additions & 91 deletions src/System.Private.CoreLib/shared/System/Threading/Tasks/Future.cs
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,8 @@ internal bool TrySetResult(TResult result)
{
Debug.Assert(m_action == null, "Task<T>.TrySetResult(): non-null m_action");

bool returnValue = false;

// "Reserve" the completion for this task, while making sure that: (1) No prior reservation
// has been made, (2) The result has not already been set, (3) An exception has not previously
// been recorded, and (4) Cancellation has not been requested.
Expand All @@ -411,10 +413,10 @@ internal bool TrySetResult(TResult result)
props.SetCompleted();
}
FinishContinuations();
return true;
returnValue = true;
}

return false;
return returnValue;
}

// Transitions the promise task into a successfully completed state with the specified result.
Expand Down Expand Up @@ -491,95 +493,6 @@ internal TResult GetResultCore(bool waitCompletionNotification)
return m_result;
}

// Allow multiple exceptions to be assigned to a promise-style task.
// This is useful when a TaskCompletionSource<T> stands in as a proxy
// for a "real" task (as we do in Unwrap(), ContinueWhenAny() and ContinueWhenAll())
// and the "real" task ends up with multiple exceptions, which is possible when
// a task has children.
//
// Called from TaskCompletionSource<T>.SetException(IEnumerable<Exception>).
internal bool TrySetException(object exceptionObject)
{
Debug.Assert(m_action == null, "Task<T>.TrySetException(): non-null m_action");

// TCS.{Try}SetException() should have checked for this
Debug.Assert(exceptionObject != null, "Expected non-null exceptionObject argument");

// Only accept these types.
Debug.Assert(
(exceptionObject is Exception) || (exceptionObject is IEnumerable<Exception>) ||
(exceptionObject is ExceptionDispatchInfo) || (exceptionObject is IEnumerable<ExceptionDispatchInfo>),
"Expected exceptionObject to be either Exception, ExceptionDispatchInfo, or IEnumerable<> of one of those");

bool returnValue = false;

// "Reserve" the completion for this task, while making sure that: (1) No prior reservation
// has been made, (2) The result has not already been set, (3) An exception has not previously
// been recorded, and (4) Cancellation has not been requested.
//
// If the reservation is successful, then add the exception(s) and finish completion processing.
//
// The lazy initialization may not be strictly necessary, but I'd like to keep it here
// anyway. Some downstream logic may depend upon an inflated m_contingentProperties.
EnsureContingentPropertiesInitialized();
if (AtomicStateUpdate(TASK_STATE_COMPLETION_RESERVED,
TASK_STATE_COMPLETION_RESERVED | TASK_STATE_RAN_TO_COMPLETION | TASK_STATE_FAULTED | TASK_STATE_CANCELED))
{
AddException(exceptionObject); // handles singleton exception or exception collection
Finish(false);
returnValue = true;
}

return returnValue;
}

// internal helper function breaks out logic used by TaskCompletionSource and AsyncMethodBuilder
// If the tokenToRecord is not None, it will be stored onto the task.
// This method is only valid for promise tasks.
internal bool TrySetCanceled(CancellationToken tokenToRecord)
{
return TrySetCanceled(tokenToRecord, null);
}

// internal helper function breaks out logic used by TaskCompletionSource and AsyncMethodBuilder
// If the tokenToRecord is not None, it will be stored onto the task.
// If the OperationCanceledException is not null, it will be stored into the task's exception holder.
// This method is only valid for promise tasks.
internal bool TrySetCanceled(CancellationToken tokenToRecord, object cancellationException)
{
Debug.Assert(m_action == null, "Task<T>.TrySetCanceled(): non-null m_action");
#if DEBUG
var ceAsEdi = cancellationException as ExceptionDispatchInfo;
Debug.Assert(
cancellationException == null ||
cancellationException is OperationCanceledException ||
(ceAsEdi != null && ceAsEdi.SourceException is OperationCanceledException),
"Expected null or an OperationCanceledException");
#endif

bool returnValue = false;

// "Reserve" the completion for this task, while making sure that: (1) No prior reservation
// has been made, (2) The result has not already been set, (3) An exception has not previously
// been recorded, and (4) Cancellation has not been requested.
//
// If the reservation is successful, then record the cancellation and finish completion processing.
//
// Note: I had to access static Task variables through Task<object>
// instead of Task, because I have a property named Task and that
// was confusing the compiler.
if (AtomicStateUpdate(Task<object>.TASK_STATE_COMPLETION_RESERVED,
Task<object>.TASK_STATE_COMPLETION_RESERVED | Task<object>.TASK_STATE_CANCELED |
Task<object>.TASK_STATE_FAULTED | Task<object>.TASK_STATE_RAN_TO_COMPLETION))
{
RecordInternalCancellationRequest(tokenToRecord, cancellationException);
CancellationCleanupLogic(); // perform cancellation cleanup actions
returnValue = true;
}

return returnValue;
}

/// <summary>
/// Provides access to factory methods for creating <see cref="Task{TResult}"/> instances.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ internal static Task<TResult> FromAsyncImpl(Func<AsyncCallback, object, IAsyncRe
Task.RemoveFromActiveTasks(promise);

// Make sure we don't leave promise "dangling".
promise.TrySetResult(default);
promise.TrySetResult();
throw;
}

Expand Down Expand Up @@ -917,7 +917,7 @@ internal static Task<TResult> FromAsyncImpl<TArg1>(Func<TArg1, AsyncCallback, ob
Task.RemoveFromActiveTasks(promise);

// Make sure we don't leave promise "dangling".
promise.TrySetResult(default);
promise.TrySetResult();
throw;
}

Expand Down Expand Up @@ -1042,7 +1042,7 @@ internal static Task<TResult> FromAsyncImpl<TArg1, TArg2>(Func<TArg1, TArg2, Asy
Task.RemoveFromActiveTasks(promise);

// Make sure we don't leave promise "dangling".
promise.TrySetResult(default);
promise.TrySetResult();
throw;
}

Expand Down Expand Up @@ -1175,7 +1175,7 @@ internal static Task<TResult> FromAsyncImpl<TArg1, TArg2, TArg3>(Func<TArg1, TAr
Task.RemoveFromActiveTasks(promise);

// Make sure we don't leave the promise "dangling".
promise.TrySetResult(default);
promise.TrySetResult();
throw;
}

Expand Down
Loading