Skip to content

Commit

Permalink
Following feedback on dotnet#579 (dotnet#579 (comment)), implemented …
Browse files Browse the repository at this point in the history
…synchronization using SemaphoreSlim to avoid race conditions on completion of _currentTask.Wait.
  • Loading branch information
JAZDaddy committed Oct 14, 2020
1 parent 64a50c5 commit 9eaa99f
Showing 1 changed file with 20 additions and 8 deletions.
Expand Up @@ -104,21 +104,33 @@ internal enum SNISMUXFlags

internal class SslStreamProxy : SslStream
{
private Task _currentTask;
private readonly SemaphoreSlim _semaphore;

public SslStreamProxy(Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback)
public SslStreamProxy(Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback userCertificateValidationCallback)
: base(innerStream, leaveInnerStreamOpen, userCertificateValidationCallback)
{ }
{
_semaphore = new SemaphoreSlim(1); /* granting one concurrent write on innerStream */
}

// Prevent the WriteAsync's collision
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
if (_currentTask != null && _currentTask.Status != TaskStatus.RanToCompletion)
await _semaphore.WaitAsync(cancellationToken);
try
{
_currentTask.Wait(cancellationToken);
await base.WriteAsync(buffer, offset, count, cancellationToken);
}
_currentTask = base.WriteAsync(buffer, offset, count, cancellationToken);
return _currentTask;
finally
{
_semaphore.Release();
}
return;
}

protected override void Dispose(bool disposing)
{
_semaphore?.Dispose();
base.Dispose(disposing);
}
}

Expand Down

0 comments on commit 9eaa99f

Please sign in to comment.