From 6c56b6a2efbdbfa8e2c06c643994e91b3b78425f Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 6 Aug 2024 20:04:39 -0400 Subject: [PATCH] Use a partial extension method to strip out unnecessary state writes in Release mode. --- Package/Core/InternalShared/DebugInternal.cs | 11 +++++++++++ Package/Core/Linq/Generators/Range.cs | 4 +--- Package/Core/Linq/Generators/Repeat.cs | 4 +--- Package/Core/Linq/Generators/Return.cs | 4 +--- .../Internal/PromiseEachGroupInternal.cs | 11 +++++------ Package/Core/Promises/Internal/EachInternal.cs | 8 +++----- .../Threading/Internal/AsyncAutoResetEventInternal.cs | 2 +- .../Threading/Internal/AsyncCountdownEventInternal.cs | 2 +- Package/Core/Threading/Internal/AsyncLockInternal.cs | 4 ++-- .../Internal/AsyncManualResetEventInternal.cs | 2 +- .../Internal/AsyncReaderWriterLockInternal.cs | 8 ++++---- .../Core/Threading/Internal/AsyncSemaphoreInternal.cs | 2 +- 12 files changed, 32 insertions(+), 30 deletions(-) diff --git a/Package/Core/InternalShared/DebugInternal.cs b/Package/Core/InternalShared/DebugInternal.cs index 1bba1da7..60bd5b8b 100644 --- a/Package/Core/InternalShared/DebugInternal.cs +++ b/Package/Core/InternalShared/DebugInternal.cs @@ -464,6 +464,17 @@ partial void RemoveComplete(PromiseRefBase completePromise) internal static string GetFormattedStacktrace(ITraceable traceable) => null; #endif // PROMISE_DEBUG + + // Dispose validates the state is not pending in Debug or Developer mode, + // so we only set the state for early dispose in those modes. + static partial void PrepareEarlyDispose(this PromiseRefBase promise); + +#if PROMISE_DEBUG || PROTO_PROMISE_DEVELOPER_MODE + static partial void PrepareEarlyDispose(this PromiseRefBase promise) + { + promise.SetCompletionState(Promise.State.Resolved); + } +#endif } // class Internal partial struct Promise diff --git a/Package/Core/Linq/Generators/Range.cs b/Package/Core/Linq/Generators/Range.cs index 6b484937..c3e1ddaa 100644 --- a/Package/Core/Linq/Generators/Range.cs +++ b/Package/Core/Linq/Generators/Range.cs @@ -117,9 +117,7 @@ internal override Promise DisposeAsync(int id) new private void Dispose() { -#if PROMISE_DEBUG || PROTO_PROMISE_DEVELOPER_MODE - SetCompletionState(Promise.State.Resolved); -#endif + this.PrepareEarlyDispose(); base.Dispose(); _disposed = true; ObjectPool.MaybeRepool(this); diff --git a/Package/Core/Linq/Generators/Repeat.cs b/Package/Core/Linq/Generators/Repeat.cs index 44e0d64c..9ff92506 100644 --- a/Package/Core/Linq/Generators/Repeat.cs +++ b/Package/Core/Linq/Generators/Repeat.cs @@ -120,9 +120,7 @@ internal override Promise DisposeAsync(int id) new private void Dispose() { -#if PROMISE_DEBUG || PROTO_PROMISE_DEVELOPER_MODE - SetCompletionState(Promise.State.Resolved); -#endif + this.PrepareEarlyDispose(); base.Dispose(); _current = default; _disposed = true; diff --git a/Package/Core/Linq/Generators/Return.cs b/Package/Core/Linq/Generators/Return.cs index c6166906..ce52ff8f 100644 --- a/Package/Core/Linq/Generators/Return.cs +++ b/Package/Core/Linq/Generators/Return.cs @@ -91,9 +91,7 @@ internal override Promise DisposeAsync(int id) new private void Dispose() { -#if PROMISE_DEBUG || PROTO_PROMISE_DEVELOPER_MODE - SetCompletionState(Promise.State.Resolved); -#endif + this.PrepareEarlyDispose(); base.Dispose(); _current = default; _disposed = true; diff --git a/Package/Core/PromiseGroups/Internal/PromiseEachGroupInternal.cs b/Package/Core/PromiseGroups/Internal/PromiseEachGroupInternal.cs index e05fa152..3ad29d3b 100644 --- a/Package/Core/PromiseGroups/Internal/PromiseEachGroupInternal.cs +++ b/Package/Core/PromiseGroups/Internal/PromiseEachGroupInternal.cs @@ -105,12 +105,6 @@ private void CancelGroup() { ValidateNoPending(); -#if PROMISE_DEBUG || PROTO_PROMISE_DEVELOPER_MODE - SetCompletionState(Promise.State.Resolved); -#endif - // MoveNextAsync/DisposeAsync may have completed synchronously, in which case this will never have had a waiter added to it. - // So we need to mark it awaited to prevent the finalizer from reporting it as not awaited. - WasAwaitedOrForgotten = true; base.Dispose(); _current = default; _cancelationException = null; @@ -150,6 +144,11 @@ internal override Promise DisposeAsync(int id) } var exception = GetAggregateException(); + + // MoveNextAsync may have completed synchronously, or not called at all, in which case this will never have had a waiter added to it or had its promise state set. + // So we need to mark it awaited to prevent the finalizer from reporting it as not awaited, and prepare the dispose. + this.PrepareEarlyDispose(); + WasAwaitedOrForgotten = true; Dispose(); return exception == null ? Promise.Resolved() diff --git a/Package/Core/Promises/Internal/EachInternal.cs b/Package/Core/Promises/Internal/EachInternal.cs index 1b0339a1..28b5bd61 100644 --- a/Package/Core/Promises/Internal/EachInternal.cs +++ b/Package/Core/Promises/Internal/EachInternal.cs @@ -86,11 +86,9 @@ internal void AddPromise(PromiseRefBase promise, short id) { ValidateNoPending(); -#if PROMISE_DEBUG || PROTO_PROMISE_DEVELOPER_MODE - SetCompletionState(Promise.State.Resolved); -#endif - // MoveNextAsync/DisposeAsync may have completed synchronously, in which case this will never have had a waiter added to it. - // So we need to mark it awaited to prevent the finalizer from reporting it as not awaited. + // MoveNextAsync/DisposeAsync may have completed synchronously, or not called at all, in which case this will never have had a waiter added to it or had its promise state set. + // So we need to mark it awaited to prevent the finalizer from reporting it as not awaited, and prepare the dispose. + this.PrepareEarlyDispose(); WasAwaitedOrForgotten = true; base.Dispose(); _disposed = true; diff --git a/Package/Core/Threading/Internal/AsyncAutoResetEventInternal.cs b/Package/Core/Threading/Internal/AsyncAutoResetEventInternal.cs index ffcf787b..1529b7de 100644 --- a/Package/Core/Threading/Internal/AsyncAutoResetEventInternal.cs +++ b/Package/Core/Threading/Internal/AsyncAutoResetEventInternal.cs @@ -48,7 +48,7 @@ internal override void MaybeDispose() [MethodImpl(InlineOption)] internal void DisposeImmediate() { - SetCompletionState(Promise.State.Resolved); + this.PrepareEarlyDispose(); MaybeDispose(); } diff --git a/Package/Core/Threading/Internal/AsyncCountdownEventInternal.cs b/Package/Core/Threading/Internal/AsyncCountdownEventInternal.cs index db4ee86a..62e93063 100644 --- a/Package/Core/Threading/Internal/AsyncCountdownEventInternal.cs +++ b/Package/Core/Threading/Internal/AsyncCountdownEventInternal.cs @@ -48,7 +48,7 @@ internal override void MaybeDispose() [MethodImpl(InlineOption)] internal void DisposeImmediate() { - SetCompletionState(Promise.State.Resolved); + this.PrepareEarlyDispose(); MaybeDispose(); } diff --git a/Package/Core/Threading/Internal/AsyncLockInternal.cs b/Package/Core/Threading/Internal/AsyncLockInternal.cs index fd652dc2..a97f7eae 100644 --- a/Package/Core/Threading/Internal/AsyncLockInternal.cs +++ b/Package/Core/Threading/Internal/AsyncLockInternal.cs @@ -74,7 +74,7 @@ internal override void MaybeDispose() [MethodImpl(InlineOption)] internal void DisposeImmediate() { - SetCompletionState(Promise.State.Resolved); + this.PrepareEarlyDispose(); MaybeDispose(); } @@ -156,7 +156,7 @@ internal override void MaybeDispose() [MethodImpl(InlineOption)] internal void DisposeImmediate() { - SetCompletionState(Promise.State.Resolved); + this.PrepareEarlyDispose(); MaybeDispose(); } diff --git a/Package/Core/Threading/Internal/AsyncManualResetEventInternal.cs b/Package/Core/Threading/Internal/AsyncManualResetEventInternal.cs index 3ffe4a0a..74c39a6d 100644 --- a/Package/Core/Threading/Internal/AsyncManualResetEventInternal.cs +++ b/Package/Core/Threading/Internal/AsyncManualResetEventInternal.cs @@ -48,7 +48,7 @@ internal override void MaybeDispose() [MethodImpl(InlineOption)] internal void DisposeImmediate() { - SetCompletionState(Promise.State.Resolved); + this.PrepareEarlyDispose(); MaybeDispose(); } diff --git a/Package/Core/Threading/Internal/AsyncReaderWriterLockInternal.cs b/Package/Core/Threading/Internal/AsyncReaderWriterLockInternal.cs index 10e40981..f72cf013 100644 --- a/Package/Core/Threading/Internal/AsyncReaderWriterLockInternal.cs +++ b/Package/Core/Threading/Internal/AsyncReaderWriterLockInternal.cs @@ -52,7 +52,7 @@ internal override void MaybeDispose() [MethodImpl(InlineOption)] internal void DisposeImmediate() { - SetCompletionState(Promise.State.Resolved); + this.PrepareEarlyDispose(); MaybeDispose(); } @@ -115,7 +115,7 @@ internal override void MaybeDispose() [MethodImpl(InlineOption)] internal void DisposeImmediate() { - SetCompletionState(Promise.State.Resolved); + this.PrepareEarlyDispose(); MaybeDispose(); } @@ -178,7 +178,7 @@ internal override void MaybeDispose() [MethodImpl(InlineOption)] internal void DisposeImmediate() { - SetCompletionState(Promise.State.Resolved); + this.PrepareEarlyDispose(); MaybeDispose(); } @@ -241,7 +241,7 @@ internal override void MaybeDispose() [MethodImpl(InlineOption)] internal void DisposeImmediate() { - SetCompletionState(Promise.State.Resolved); + this.PrepareEarlyDispose(); MaybeDispose(); } diff --git a/Package/Core/Threading/Internal/AsyncSemaphoreInternal.cs b/Package/Core/Threading/Internal/AsyncSemaphoreInternal.cs index c6fd79bd..84085d3c 100644 --- a/Package/Core/Threading/Internal/AsyncSemaphoreInternal.cs +++ b/Package/Core/Threading/Internal/AsyncSemaphoreInternal.cs @@ -48,7 +48,7 @@ internal override void MaybeDispose() [MethodImpl(InlineOption)] internal void DisposeImmediate() { - SetCompletionState(Promise.State.Resolved); + this.PrepareEarlyDispose(); MaybeDispose(); }