Skip to content

Commit

Permalink
Fix oversize buffer reset for multiplexing (#4101)
Browse files Browse the repository at this point in the history
Fixes #4099
  • Loading branch information
vonzshik authored Nov 5, 2021
1 parent 8ff6b9d commit 0b430d6
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/Npgsql/Internal/NpgsqlConnector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,7 @@ async Task MultiplexingReadLoop()
// the connector's write lock has been released (long waiting will never occur here).
SpinWait.SpinUntil(() => MultiplexAsyncWritingLock == 0 || IsBroken);

ResetReadBuffer();
_connectorSource.Return(this);
}
}
Expand Down Expand Up @@ -2161,7 +2162,7 @@ internal async Task Reset(bool async)
/// This switches us back to the original one and returns the buffer to <see cref="ArrayPool{T}" />.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void ResetReadBuffer()
void ResetReadBuffer()
{
if (_origReadBuffer != null)
{
Expand Down
2 changes: 0 additions & 2 deletions src/Npgsql/NpgsqlDataReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1033,8 +1033,6 @@ internal async Task Cleanup(bool async, bool connectionClosing = false, bool isD
var connector = Connector;
UnbindIfNecessary();

connector.ResetReadBuffer();

// TODO: Refactor... Use proper scope
_connection.Connector = null;
connector.Connection = null;
Expand Down
47 changes: 47 additions & 0 deletions test/Npgsql.Tests/BugTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
using Npgsql.Tests.Support;

using static Npgsql.Tests.TestUtil;
using Npgsql.BackendMessages;
using Npgsql.TypeMapping;

namespace Npgsql.Tests
{
Expand Down Expand Up @@ -1381,5 +1383,50 @@ public async Task Bug3924()
Assert.DoesNotThrowAsync(cmd.ExecuteNonQueryAsync);
}
}

[Test]
[IssueLink("https://github.com/npgsql/npgsql/issues/4099")]
public async Task Bug4099()
{
var csb = new NpgsqlConnectionStringBuilder(ConnectionString)
{
Multiplexing = true,
MaxPoolSize = 1
};
await using var postmaster = PgPostmasterMock.Start(csb.ConnectionString);
await using var firstConn = await OpenConnectionAsync(postmaster.ConnectionString);
await using var secondConn = await OpenConnectionAsync(postmaster.ConnectionString);

var byteArrayLength = csb.WriteBufferSize + 100;
var firstQuery = firstConn.ExecuteScalarAsync("SELECT data");

var server = await postmaster.WaitForServerConnection();
await server.ExpectExtendedQuery();

var secondQuery = secondConn.ExecuteScalarAsync("SELECT other_data");
await server.ExpectExtendedQuery();

var data = new byte[10000];
await server
.WriteParseComplete()
.WriteBindComplete()
.WriteRowDescription(new FieldDescription(PostgresTypeOIDs.Bytea))
.WriteDataRowWithFlush(data);

var otherData = new byte[10];
await server
.WriteCommandComplete()
.WriteReadyForQuery()
.WriteParseComplete()
.WriteBindComplete()
.WriteRowDescription(new FieldDescription(PostgresTypeOIDs.Bytea))
.WriteDataRow(otherData)
.WriteCommandComplete()
.WriteReadyForQuery()
.FlushAsync();

Assert.That(data, Is.EquivalentTo((byte[])(await firstQuery)!));
Assert.That(otherData, Is.EquivalentTo((byte[])(await secondQuery)!));
}
}
}

0 comments on commit 0b430d6

Please sign in to comment.