Fix race in Restart during Close task (#1263)

This commit is contained in:
BrennanConroy 2018-01-31 15:51:33 -08:00 committed by GitHub
parent 1f810fd535
commit 8cecca07a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 27 additions and 6 deletions

View File

@ -516,24 +516,45 @@ namespace Microsoft.AspNetCore.Sockets.Client
// _startTask is returned to the user and they should handle exceptions.
}
TaskCompletionSource<object> closeTcs = null;
Task receiveLoopTask = null;
ITransport transport = null;
lock (_stateChangeLock)
{
// Copy locals in lock to prevent a race when the server closes the connection and StopAsync is called
// at the same time
if (_connectionState != ConnectionState.Connected)
{
// If not Connected then someone else disconnected while StopAsync was in progress, we can now NO-OP
return;
}
// Create locals of relevant member variables to prevent a race when Closed event triggers a connect
// while StopAsync is still running
closeTcs = _closeTcs;
receiveLoopTask = _receiveLoopTask;
transport = _transport;
}
if (_transportChannel != null)
{
Output.TryComplete();
}
if (_transport != null)
if (transport != null)
{
await _transport.StopAsync();
await transport.StopAsync();
}
if (_receiveLoopTask != null)
if (receiveLoopTask != null)
{
await _receiveLoopTask;
await receiveLoopTask;
}
if (_closeTcs != null)
if (closeTcs != null)
{
await _closeTcs.Task;
await closeTcs.Task;
}
}