Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/FirebirdSql.Data.FirebirdClient.Tests/FbConnectionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,40 @@ public async Task ConnectionTimeoutUsingCancellationToken()
}
}

[Test]
public async Task PooledConnectionUsableAfterCancelledBeginTransaction()
{
if (!EnsureServerType(FbServerType.Default))
return;

// The cancellation token reaches the socket read, so the transaction response stays unread.
var csb = BuildConnectionStringBuilder(ServerType, Compression, WireCrypt);
csb.Pooling = true;
csb.MinPoolSize = 0;
csb.MaxPoolSize = 1;
var connectionString = csb.ToString();
FbConnection.ClearPool(connectionString);

using (var cancellation = new CancellationTokenSource())
await using (var connection = new FbConnection(connectionString))
{
await connection.OpenAsync();
var beginning = connection.BeginTransactionAsync(cancellation.Token);
cancellation.Cancel();
Assert.CatchAsync<OperationCanceledException>(async () => await beginning);
}

await using (var connection = new FbConnection(connectionString))
{
await connection.OpenAsync();
await using (var command = connection.CreateCommand())
{
command.CommandText = "select 1 from rdb$database";
Assert.AreEqual(1, Convert.ToInt32(await command.ExecuteScalarAsync()));
}
}
}

[Test]
public async Task SrpWithLeadingZeros()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public FirebirdNetworkHandlingWrapper(IDataProvider dataProvider)

public int Read(byte[] buffer, int offset, int count)
{
CheckIOState();
if (_inputBuffer.Count < count)
{
var readBuffer = _readBuffer;
Expand Down Expand Up @@ -89,6 +90,7 @@ public int Read(byte[] buffer, int offset, int count)
}
public async ValueTask<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken = default)
{
CheckIOState();
if (_inputBuffer.Count < count)
{
var readBuffer = _readBuffer;
Expand All @@ -102,6 +104,11 @@ public async ValueTask<int> ReadAsync(byte[] buffer, int offset, int count, Canc
IOFailed = true;
throw;
}
catch (OperationCanceledException)
{
IOFailed = true;
throw;
}
if (read != 0)
{
if (_decryptor != null)
Expand Down Expand Up @@ -134,6 +141,7 @@ public ValueTask WriteAsync(byte[] buffer, int offset, int count, CancellationTo

public void Flush()
{
CheckIOState();
var buffer = _outputBuffer.ToArray();
_outputBuffer.Clear();
var count = buffer.Length;
Expand All @@ -159,6 +167,7 @@ public void Flush()
}
public async ValueTask FlushAsync(CancellationToken cancellationToken = default)
{
CheckIOState();
var buffer = _outputBuffer.ToArray();
_outputBuffer.Clear();
var count = buffer.Length;
Expand All @@ -181,6 +190,11 @@ public async ValueTask FlushAsync(CancellationToken cancellationToken = default)
IOFailed = true;
throw;
}
catch (OperationCanceledException)
{
IOFailed = true;
throw;
}
}

public void StartCompression()
Expand All @@ -196,6 +210,12 @@ public void StartEncryption(byte[] key)
_decryptor = CreateCipher(key);
}

void CheckIOState()
{
if (IOFailed)
throw new IOException("Error reading data from the connection.");
}

int ReadFromInputBuffer(byte[] buffer, int offset, int count)
{
var read = Math.Min(count, _inputBuffer.Count);
Expand Down
24 changes: 22 additions & 2 deletions src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,17 @@ public override void Close()
}
}
catch
{ }
{
if (_innerConnection != null)
{
if (_options.Pooling)
{
FbConnectionPoolManager.Instance.Release(_innerConnection, returnToAvailable: false);
}

DisconnectEnlistedHelper();
}
}
finally
{
OnStateChange(_state, ConnectionState.Closed);
Expand Down Expand Up @@ -810,7 +820,17 @@ public override async Task CloseAsync()
}
}
catch
{ }
{
if (_innerConnection != null)
{
if (_options.Pooling)
{
FbConnectionPoolManager.Instance.Release(_innerConnection, false);
}

await DisconnectEnlistedHelper().ConfigureAwait(false);
}
}
finally
{
OnStateChange(_state, ConnectionState.Closed);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,11 @@ public async Task<FbTransaction> BeginTransactionAsync(IsolationLevel level, str
await DisposeTransactionAsync(cancellationToken).ConfigureAwait(false);
throw FbException.Create(ex);
}
catch (OperationCanceledException)
{
await DisposeTransactionAsync(CancellationToken.None).ConfigureAwait(false);
throw;
}

return _activeTransaction;
}
Expand Down Expand Up @@ -412,6 +417,11 @@ public async Task<FbTransaction> BeginTransactionAsync(FbTransactionOptions opti
await DisposeTransactionAsync(cancellationToken).ConfigureAwait(false);
throw FbException.Create(ex);
}
catch (OperationCanceledException)
{
await DisposeTransactionAsync(CancellationToken.None).ConfigureAwait(false);
throw;
}

return _activeTransaction;
}
Expand Down