-
Couldn't load subscription status.
- Fork 316
Fix async deadlock issue when sending attention fails due to network failure #1766
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
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 |
|---|---|---|
|
|
@@ -2401,9 +2401,9 @@ private void OnTimeoutAsync(object state) | |
| } | ||
| } | ||
|
|
||
| private bool OnTimeoutSync() | ||
| private bool OnTimeoutSync(bool asyncClose = false) | ||
cheenamalhotra marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| return OnTimeoutCore(TimeoutState.Running, TimeoutState.ExpiredSync); | ||
| return OnTimeoutCore(TimeoutState.Running, TimeoutState.ExpiredSync, asyncClose); | ||
| } | ||
|
|
||
| /// <summary> | ||
|
|
@@ -2412,8 +2412,9 @@ private bool OnTimeoutSync() | |
| /// </summary> | ||
| /// <param name="expectedState">the state that is the expected current state, state will change only if this is correct</param> | ||
| /// <param name="targetState">the state that will be changed to if the expected state is correct</param> | ||
| /// <param name="asyncClose">any close action to be taken by an async task to avoid deadlock.</param> | ||
| /// <returns>boolean value indicating whether the call changed the timeout state</returns> | ||
| private bool OnTimeoutCore(int expectedState, int targetState) | ||
| private bool OnTimeoutCore(int expectedState, int targetState, bool asyncClose = false) | ||
| { | ||
| Debug.Assert(targetState == TimeoutState.ExpiredAsync || targetState == TimeoutState.ExpiredSync, "OnTimeoutCore must have an expiry state as the targetState"); | ||
|
|
||
|
|
@@ -2447,7 +2448,7 @@ private bool OnTimeoutCore(int expectedState, int targetState) | |
| { | ||
| try | ||
| { | ||
| SendAttention(mustTakeWriteLock: true); | ||
| SendAttention(mustTakeWriteLock: true, asyncClose); | ||
| } | ||
| catch (Exception e) | ||
| { | ||
|
|
@@ -2988,7 +2989,7 @@ public void ReadAsyncCallback(IntPtr key, IntPtr packet, UInt32 error) | |
| // synchrnously and then call OnTimeoutSync to force an atomic change of state. | ||
| if (TimeoutHasExpired) | ||
| { | ||
| OnTimeoutSync(); | ||
| OnTimeoutSync(asyncClose: true); | ||
| } | ||
|
|
||
| // try to change to the stopped state but only do so if currently in the running state | ||
|
|
@@ -3475,7 +3476,7 @@ private void CancelWritePacket() | |
|
|
||
| #pragma warning disable 420 // a reference to a volatile field will not be treated as volatile | ||
|
|
||
| private Task SNIWritePacket(SNIHandle handle, SNIPacket packet, out UInt32 sniError, bool canAccumulate, bool callerHasConnectionLock) | ||
| private Task SNIWritePacket(SNIHandle handle, SNIPacket packet, out UInt32 sniError, bool canAccumulate, bool callerHasConnectionLock, bool asyncClose = false) | ||
| { | ||
| // Check for a stored exception | ||
| var delayedException = Interlocked.Exchange(ref _delayedWriteAsyncCallbackException, null); | ||
|
|
@@ -3566,7 +3567,7 @@ private Task SNIWritePacket(SNIHandle handle, SNIPacket packet, out UInt32 sniEr | |
| SqlClientEventSource.Log.TryTraceEvent("<sc.TdsParser.WritePacket|Info> write async returned error code {0}", (int)error); | ||
|
|
||
| AddError(_parser.ProcessSNIError(this)); | ||
| ThrowExceptionAndWarning(); | ||
| ThrowExceptionAndWarning(false, asyncClose); | ||
| } | ||
| AssertValidState(); | ||
| completion.SetResult(null); | ||
|
|
@@ -3603,7 +3604,7 @@ private Task SNIWritePacket(SNIHandle handle, SNIPacket packet, out UInt32 sniEr | |
| { | ||
| SqlClientEventSource.Log.TryTraceEvent("<sc.TdsParser.WritePacket|Info> write async returned error code {0}", (int)sniError); | ||
| AddError(_parser.ProcessSNIError(this)); | ||
| ThrowExceptionAndWarning(callerHasConnectionLock); | ||
| ThrowExceptionAndWarning(callerHasConnectionLock, false); | ||
|
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. @cheenamalhotra Did we purposely call This seems like a mistake and I've changed this line to match netcore in PR #2073. |
||
| } | ||
| AssertValidState(); | ||
| } | ||
|
|
@@ -3613,7 +3614,7 @@ private Task SNIWritePacket(SNIHandle handle, SNIPacket packet, out UInt32 sniEr | |
| #pragma warning restore 420 | ||
|
|
||
| // Sends an attention signal - executing thread will consume attn. | ||
| internal void SendAttention(bool mustTakeWriteLock = false) | ||
| internal void SendAttention(bool mustTakeWriteLock = false, bool asyncClose = false) | ||
| { | ||
| if (!_attentionSent) | ||
| { | ||
|
|
@@ -3660,7 +3661,7 @@ internal void SendAttention(bool mustTakeWriteLock = false) | |
|
|
||
| UInt32 sniError; | ||
| _parser._asyncWrite = false; // stop async write | ||
| SNIWritePacket(Handle, attnPacket, out sniError, canAccumulate: false, callerHasConnectionLock: false); | ||
| SNIWritePacket(Handle, attnPacket, out sniError, canAccumulate: false, callerHasConnectionLock: false, asyncClose); | ||
| SqlClientEventSource.Log.TryTraceEvent("<sc.TdsParser.SendAttention|{0}> Send Attention ASync.", "Info"); | ||
| } | ||
| finally | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.