-
Notifications
You must be signed in to change notification settings - Fork 5.3k
[S.N.Quic] Observe exceptions in ResettableValueTaskSource #114226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d92daa7
00383c4
2c6cd10
9de51bb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -52,7 +52,7 @@ public ResettableValueTaskSource() | |
| public Action<object?> CancellationAction { init { _cancellationAction = value; } } | ||
|
|
||
| /// <summary> | ||
| /// Returns <c>true</c> is this task source has entered its final state, i.e. <see cref="TrySetResult(bool)"/> or <see cref="TrySetException(Exception, bool)"/> | ||
| /// Returns <c>true</c> is this task source has entered its final state, i.e. <see cref="TrySetResult(bool)"/> or <see cref="TrySetException(Exception)"/> | ||
| /// was called with <c>final</c> set to <c>true</c> and the result was propagated. | ||
| /// </summary> | ||
| public bool IsCompleted => (State)Volatile.Read(ref Unsafe.As<State, byte>(ref _state)) == State.Completed; | ||
|
|
@@ -173,6 +173,7 @@ private bool TryComplete(Exception? exception, bool final) | |
| // Unblock the current task source and in case of a final also the final task source. | ||
| if (exception is not null) | ||
| { | ||
| Debug.Assert(final); | ||
| // Set up the exception stack trace for the caller. | ||
| exception = exception.StackTrace is null ? ExceptionDispatchInfo.SetCurrentStackTrace(exception) : exception; | ||
| if (state is State.None or State.Awaiting) | ||
|
|
@@ -192,7 +193,7 @@ private bool TryComplete(Exception? exception, bool final) | |
| if (_finalTaskSource.TryComplete(exception)) | ||
| { | ||
| // Signal the final task only if we don't have another result in the value task source. | ||
| // In that case, the final task will be signalled after the value task result is retrieved. | ||
| // In that case, the final task will be signaled after the value task result is retrieved. | ||
| if (state != State.Ready) | ||
| { | ||
| _finalTaskSource.TrySignal(out _); | ||
|
|
@@ -226,15 +227,14 @@ public bool TrySetResult(bool final = false) | |
| } | ||
|
|
||
| /// <summary> | ||
| /// Tries to transition from <see cref="State.Awaiting"/> to either <see cref="State.Ready"/> or <see cref="State.Completed"/>, depending on the value of <paramref name="final"/>. | ||
| /// Only the first call is able to do that with the exception of <c>TrySetResult()</c> followed by <c>TrySetResult(true)</c>, which will both return <c>true</c>. | ||
| /// Tries to transition from <see cref="State.Awaiting"/> to <see cref="State.Completed"/>, setting an exception. | ||
| /// Only the first call is able to do that. | ||
| /// </summary> | ||
| /// <param name="final">Whether this is the final transition to <see cref="State.Completed" /> or just a transition into <see cref="State.Ready"/> from which the task source can be reset back to <see cref="State.None"/>.</param> | ||
| /// <param name="exception">The exception to set as a result of the value task.</param> | ||
| /// <returns><c>true</c> if this is the first call that set the result; otherwise, <c>false</c>.</returns> | ||
| public bool TrySetException(Exception exception, bool final = false) | ||
| public bool TrySetException(Exception exception) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just for the explanation: the It could have also gone the other way by making Anyway, this is not a hill I want to die on, so keep the change as-is if you prefer it this way.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't plan to do further refactors in this PR, just leaving my take: It would be better to make it mandatory on |
||
| { | ||
| return TryComplete(exception, final); | ||
| return TryComplete(exception, final: true); | ||
| } | ||
|
|
||
| ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) | ||
|
|
@@ -297,6 +297,7 @@ private struct FinalTaskSource | |
| private bool _isCompleted; | ||
| private bool _isSignaled; | ||
| private Exception? _exception; | ||
| private Task? _signaledTask; | ||
|
|
||
| public FinalTaskSource() | ||
| { | ||
|
|
@@ -312,9 +313,9 @@ public Task GetTask(object? keepAlive) | |
| { | ||
| if (_isSignaled) | ||
| { | ||
| return _exception is null | ||
| ? Task.CompletedTask | ||
| : Task.FromException(_exception); | ||
| _signaledTask ??= _exception is null ? Task.CompletedTask : Task.FromException(_exception); | ||
antonfirsov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| _ = _signaledTask.Exception; // Observe the exception. | ||
| return _signaledTask; | ||
| } | ||
|
|
||
| _finalTaskSource = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); | ||
|
|
@@ -350,13 +351,17 @@ public bool TrySignal(out Exception? exception) | |
| return false; | ||
| } | ||
|
|
||
| if (_exception is not null) | ||
| if (_finalTaskSource is not null) | ||
| { | ||
| _finalTaskSource?.SetException(_exception); | ||
| } | ||
| else | ||
| { | ||
| _finalTaskSource?.SetResult(); | ||
| if (_exception is not null) | ||
| { | ||
| _finalTaskSource.SetException(_exception); | ||
| _ = _finalTaskSource.Task.Exception; // Observe the exception. | ||
| } | ||
| else | ||
| { | ||
| _finalTaskSource.SetResult(); | ||
| } | ||
| } | ||
|
|
||
| exception = _exception; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.