@@ -55,7 +55,7 @@ public TimeoutState(int value)
55
55
56
56
private const int AttentionTimeoutSeconds = 5 ;
57
57
58
- private static readonly ContextCallback s_readAdyncCallbackComplete = ReadAsyncCallbackComplete ;
58
+ private static readonly ContextCallback s_readAsyncCallbackComplete = ReadAsyncCallbackComplete ;
59
59
60
60
// Ticks to consider a connection "good" after a successful I/O (10,000 ticks = 1 ms)
61
61
// The resolution of the timer is typically in the range 10 to 16 milliseconds according to msdn.
@@ -2337,9 +2337,9 @@ private void OnTimeoutAsync(object state)
2337
2337
}
2338
2338
}
2339
2339
2340
- private bool OnTimeoutSync ( )
2340
+ private bool OnTimeoutSync ( bool asyncClose = false )
2341
2341
{
2342
- return OnTimeoutCore ( TimeoutState . Running , TimeoutState . ExpiredSync ) ;
2342
+ return OnTimeoutCore ( TimeoutState . Running , TimeoutState . ExpiredSync , asyncClose ) ;
2343
2343
}
2344
2344
2345
2345
/// <summary>
@@ -2348,8 +2348,9 @@ private bool OnTimeoutSync()
2348
2348
/// </summary>
2349
2349
/// <param name="expectedState">the state that is the expected current state, state will change only if this is correct</param>
2350
2350
/// <param name="targetState">the state that will be changed to if the expected state is correct</param>
2351
+ /// <param name="asyncClose">any close action to be taken by an async task to avoid deadlock.</param>
2351
2352
/// <returns>boolean value indicating whether the call changed the timeout state</returns>
2352
- private bool OnTimeoutCore ( int expectedState , int targetState )
2353
+ private bool OnTimeoutCore ( int expectedState , int targetState , bool asyncClose = false )
2353
2354
{
2354
2355
Debug . Assert ( targetState == TimeoutState . ExpiredAsync || targetState == TimeoutState . ExpiredSync , "OnTimeoutCore must have an expiry state as the targetState" ) ;
2355
2356
@@ -2382,7 +2383,7 @@ private bool OnTimeoutCore(int expectedState, int targetState)
2382
2383
{
2383
2384
try
2384
2385
{
2385
- SendAttention ( mustTakeWriteLock : true ) ;
2386
+ SendAttention ( mustTakeWriteLock : true , asyncClose ) ;
2386
2387
}
2387
2388
catch ( Exception e )
2388
2389
{
@@ -2927,7 +2928,7 @@ public void ReadAsyncCallback(IntPtr key, PacketHandle packet, uint error)
2927
2928
// synchrnously and then call OnTimeoutSync to force an atomic change of state.
2928
2929
if ( TimeoutHasExpired )
2929
2930
{
2930
- OnTimeoutSync ( ) ;
2931
+ OnTimeoutSync ( true ) ;
2931
2932
}
2932
2933
2933
2934
// try to change to the stopped state but only do so if currently in the running state
@@ -2958,7 +2959,7 @@ public void ReadAsyncCallback(IntPtr key, PacketHandle packet, uint error)
2958
2959
{
2959
2960
if ( _executionContext != null )
2960
2961
{
2961
- ExecutionContext . Run ( _executionContext , s_readAdyncCallbackComplete , source ) ;
2962
+ ExecutionContext . Run ( _executionContext , s_readAsyncCallbackComplete , source ) ;
2962
2963
}
2963
2964
else
2964
2965
{
@@ -3441,7 +3442,7 @@ private void CancelWritePacket()
3441
3442
3442
3443
#pragma warning disable 0420 // a reference to a volatile field will not be treated as volatile
3443
3444
3444
- private Task SNIWritePacket( PacketHandle packet , out uint sniError , bool canAccumulate , bool callerHasConnectionLock )
3445
+ private Task SNIWritePacket( PacketHandle packet , out uint sniError , bool canAccumulate , bool callerHasConnectionLock , bool asyncClose = false )
3445
3446
{
3446
3447
// Check for a stored exception
3447
3448
var delayedException = Interlocked. Exchange ( ref _delayedWriteAsyncCallbackException , null ) ;
@@ -3534,7 +3535,7 @@ private Task SNIWritePacket(PacketHandle packet, out uint sniError, bool canAccu
3534
3535
{
3535
3536
SqlClientEventSource . Log . TryTraceEvent ( "TdsParserStateObject.SNIWritePacket | Info | State Object Id {0}, Write async returned error code {1}" , _objectID , ( int ) error ) ;
3536
3537
AddError ( _parser . ProcessSNIError ( this ) ) ;
3537
- ThrowExceptionAndWarning ( ) ;
3538
+ ThrowExceptionAndWarning ( false , asyncClose ) ;
3538
3539
}
3539
3540
AssertValidState ( ) ;
3540
3541
completion . SetResult ( null ) ;
@@ -3569,7 +3570,7 @@ private Task SNIWritePacket(PacketHandle packet, out uint sniError, bool canAccu
3569
3570
{
3570
3571
SqlClientEventSource . Log . TryTraceEvent ( "TdsParserStateObject.SNIWritePacket | Info | State Object Id {0}, Write async returned error code {1}" , _objectID , ( int ) sniError ) ;
3571
3572
AddError( _parser . ProcessSNIError ( this ) ) ;
3572
- ThrowExceptionAndWarning( callerHasConnectionLock ) ;
3573
+ ThrowExceptionAndWarning( callerHasConnectionLock , asyncClose ) ;
3573
3574
}
3574
3575
AssertValidState( ) ;
3575
3576
}
@@ -3581,7 +3582,7 @@ private Task SNIWritePacket(PacketHandle packet, out uint sniError, bool canAccu
3581
3582
internal abstract uint WritePacket( PacketHandle packet , bool sync ) ;
3582
3583
3583
3584
// Sends an attention signal - executing thread will consume attn.
3584
- internal void SendAttention( bool mustTakeWriteLock = false)
3585
+ internal void SendAttention( bool mustTakeWriteLock = false, bool asyncClose = false )
3585
3586
{
3586
3587
if ( ! _attentionSent )
3587
3588
{
@@ -3623,7 +3624,7 @@ internal void SendAttention(bool mustTakeWriteLock = false)
3623
3624
3624
3625
uint sniError;
3625
3626
_parser. _asyncWrite = false ; // stop async write
3626
- SNIWritePacket ( attnPacket , out sniError , canAccumulate : false , callerHasConnectionLock : false ) ;
3627
+ SNIWritePacket ( attnPacket , out sniError , canAccumulate : false , callerHasConnectionLock : false , asyncClose ) ;
3627
3628
SqlClientEventSource. Log . TryTraceEvent ( "TdsParserStateObject.SendAttention | Info | State Object Id {0}, Sent Attention." , _objectID ) ;
3628
3629
}
3629
3630
finally
0 commit comments