@@ -879,13 +879,14 @@ internal ServerSession Session
879
879
880
880
internal void Cancel ( ICancellableCommand command , int commandId , bool isCancel )
881
881
{
882
- if ( m_session ? . Id is not string sessionId || State != ConnectionState . Open || m_session ? . TryStartCancel ( command ) is not true )
882
+ // NOTE: read and cache m_session in a local variable because it can be set to null by CloseAsync on another thread
883
+ if ( m_session is not { } session || State != ConnectionState . Open || ! session . TryStartCancel ( command ) )
883
884
{
884
885
Log . IgnoringCancellationForCommand ( m_logger , commandId ) ;
885
886
return ;
886
887
}
887
888
888
- Log . CommandHasBeenCanceled ( m_logger , commandId , sessionId , isCancel ? "Cancel()" : "command timeout" ) ;
889
+ Log . CommandHasBeenCanceled ( m_logger , commandId , session . Id , isCancel ? "Cancel()" : "command timeout" ) ;
889
890
try
890
891
{
891
892
// open a dedicated connection to the server to kill the active query
@@ -894,12 +895,12 @@ internal void Cancel(ICancellableCommand command, int commandId, bool isCancel)
894
895
AutoEnlist = false ,
895
896
Pooling = false ,
896
897
} ;
897
- if ( m_session . IPEndPoint is { Address : { } ipAddress , Port : { } port } )
898
+ if ( session . IPEndPoint is { Address : { } ipAddress , Port : { } port } )
898
899
{
899
900
csb . Server = ipAddress . ToString ( ) ;
900
901
csb . Port = ( uint ) port ;
901
902
}
902
- csb . UserID = m_session . UserID ;
903
+ csb . UserID = session . UserID ;
903
904
var cancellationTimeout = GetConnectionSettings ( ) . CancellationTimeout ;
904
905
csb . ConnectionTimeout = cancellationTimeout < 1 ? 3u : ( uint ) cancellationTimeout ;
905
906
@@ -912,20 +913,20 @@ internal void Cancel(ICancellableCommand command, int commandId, bool isCancel)
912
913
#endif
913
914
using var killCommand = new MySqlCommand ( killQuerySql , connection ) ;
914
915
killCommand . CommandTimeout = cancellationTimeout < 1 ? 3 : cancellationTimeout ;
915
- m_session ? . DoCancel ( command , killCommand ) ;
916
+ session . DoCancel ( command , killCommand ) ;
916
917
}
917
918
catch ( InvalidOperationException ex )
918
919
{
919
920
// ignore a rare race condition where the connection is open at the beginning of the method, but closed by the time
920
921
// KILL QUERY is executed: https://github.com/mysql-net/MySqlConnector/issues/1002
921
- Log . IgnoringCancellationForClosedConnection ( m_logger , ex , sessionId ) ;
922
- m_session ? . AbortCancel ( command ) ;
922
+ Log . IgnoringCancellationForClosedConnection ( m_logger , ex , session . Id ) ;
923
+ session . AbortCancel ( command ) ;
923
924
}
924
925
catch ( MySqlException ex )
925
926
{
926
927
// cancelling the query failed; setting the state back to 'Querying' will allow another call to 'Cancel' to try again
927
- Log . CancelingCommandFailed ( m_logger , ex , sessionId , command . CommandId ) ;
928
- m_session ? . AbortCancel ( command ) ;
928
+ Log . CancelingCommandFailed ( m_logger , ex , session . Id , command . CommandId ) ;
929
+ session . AbortCancel ( command ) ;
929
930
}
930
931
}
931
932
0 commit comments