@@ -287,6 +287,8 @@ private async Task OpenAsync(IOBehavior? ioBehavior, CancellationToken cancellat
287287 if ( State != ConnectionState . Closed )
288288 throw new InvalidOperationException ( "Cannot Open when State is {0}." . FormatInvariant ( State ) ) ;
289289
290+ var openStartTickCount = Environment . TickCount ;
291+
290292 SetState ( ConnectionState . Connecting ) ;
291293
292294 var pool = ConnectionPool . GetPool ( m_connectionString ) ;
@@ -309,7 +311,7 @@ private async Task OpenAsync(IOBehavior? ioBehavior, CancellationToken cancellat
309311
310312 try
311313 {
312- m_session = await CreateSessionAsync ( pool , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
314+ m_session = await CreateSessionAsync ( pool , openStartTickCount , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
313315
314316 m_hasBeenOpened = true ;
315317 SetState ( ConnectionState . Open ) ;
@@ -621,7 +623,7 @@ internal void FinishQuerying(bool hasWarnings)
621623 }
622624 }
623625
624- private async ValueTask < ServerSession > CreateSessionAsync ( ConnectionPool ? pool , IOBehavior ? ioBehavior , CancellationToken cancellationToken )
626+ private async ValueTask < ServerSession > CreateSessionAsync ( ConnectionPool ? pool , int startTickCount , IOBehavior ? ioBehavior , CancellationToken cancellationToken )
625627 {
626628 var connectionSettings = GetInitializedConnectionSettings ( ) ;
627629 var actualIOBehavior = ioBehavior ?? ( connectionSettings . ForceSynchronous ? IOBehavior . Synchronous : IOBehavior . Asynchronous ) ;
@@ -633,7 +635,7 @@ private async ValueTask<ServerSession> CreateSessionAsync(ConnectionPool? pool,
633635 // the cancellation token for connection is controlled by 'cancellationToken' (if it can be cancelled), ConnectionTimeout
634636 // (from the connection string, if non-zero), or a combination of both
635637 if ( connectionSettings . ConnectionTimeout != 0 )
636- timeoutSource = new CancellationTokenSource ( TimeSpan . FromMilliseconds ( connectionSettings . ConnectionTimeoutMilliseconds ) ) ;
638+ timeoutSource = new CancellationTokenSource ( TimeSpan . FromMilliseconds ( Math . Max ( 1 , connectionSettings . ConnectionTimeoutMilliseconds - unchecked ( Environment . TickCount - startTickCount ) ) ) ) ;
637639 if ( cancellationToken . CanBeCanceled && timeoutSource is object )
638640 linkedSource = CancellationTokenSource . CreateLinkedTokenSource ( cancellationToken , timeoutSource . Token ) ;
639641 var connectToken = linkedSource ? . Token ?? timeoutSource ? . Token ?? cancellationToken ;
@@ -642,7 +644,7 @@ private async ValueTask<ServerSession> CreateSessionAsync(ConnectionPool? pool,
642644 if ( pool is object )
643645 {
644646 // this returns an open session
645- return await pool . GetSessionAsync ( this , actualIOBehavior , connectToken ) . ConfigureAwait ( false ) ;
647+ return await pool . GetSessionAsync ( this , startTickCount , actualIOBehavior , connectToken ) . ConfigureAwait ( false ) ;
646648 }
647649 else
648650 {
@@ -653,7 +655,7 @@ private async ValueTask<ServerSession> CreateSessionAsync(ConnectionPool? pool,
653655 var session = new ServerSession ( ) ;
654656 session . OwningConnection = new WeakReference < MySqlConnection > ( this ) ;
655657 Log . Info ( "Created new non-pooled Session{0}" , session . Id ) ;
656- await session . ConnectAsync ( connectionSettings , loadBalancer , actualIOBehavior , connectToken ) . ConfigureAwait ( false ) ;
658+ await session . ConnectAsync ( connectionSettings , startTickCount , loadBalancer , actualIOBehavior , connectToken ) . ConfigureAwait ( false ) ;
657659 return session ;
658660 }
659661 }
@@ -662,6 +664,10 @@ private async ValueTask<ServerSession> CreateSessionAsync(ConnectionPool? pool,
662664 var messageSuffix = ( pool ? . IsEmpty ?? false ) ? " All pooled connections are in use." : "" ;
663665 throw new MySqlException ( MySqlErrorCode . UnableToConnectToHost , "Connect Timeout expired." + messageSuffix , ex ) ;
664666 }
667+ catch ( MySqlException ex ) when ( timeoutSource ? . IsCancellationRequested ?? false )
668+ {
669+ throw new MySqlException ( MySqlErrorCode . UnableToConnectToHost , "Connect Timeout expired." , ex ) ;
670+ }
665671 finally
666672 {
667673 linkedSource ? . Dispose ( ) ;
0 commit comments