Fix MockLibuv.OnPostTask (#2260)
Prevents UvWriteReq leaks in LibuvOutputConsumerTests
This commit is contained in:
parent
cf371a4e74
commit
040ea2e6b4
|
|
@ -16,7 +16,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests.TestHelpers
|
||||||
private readonly object _postLock = new object();
|
private readonly object _postLock = new object();
|
||||||
private TaskCompletionSource<object> _onPostTcs = new TaskCompletionSource<object>();
|
private TaskCompletionSource<object> _onPostTcs = new TaskCompletionSource<object>();
|
||||||
private bool _completedOnPostTcs;
|
private bool _completedOnPostTcs;
|
||||||
private bool _sendCalled;
|
|
||||||
|
|
||||||
private bool _stopLoop;
|
private bool _stopLoop;
|
||||||
private readonly ManualResetEventSlim _loopWh = new ManualResetEventSlim();
|
private readonly ManualResetEventSlim _loopWh = new ManualResetEventSlim();
|
||||||
|
|
@ -38,29 +37,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests.TestHelpers
|
||||||
|
|
||||||
_uv_async_send = postHandle =>
|
_uv_async_send = postHandle =>
|
||||||
{
|
{
|
||||||
// Attempt to run the async send logic inline; this should succeed most of the time.
|
lock (_postLock)
|
||||||
// In the rare cases where it fails to acquire the lock, use Task.Run() so this call
|
|
||||||
// never blocks, since the real libuv never blocks.
|
|
||||||
if (Monitor.TryEnter(_postLock))
|
|
||||||
{
|
{
|
||||||
try
|
if (_completedOnPostTcs)
|
||||||
{
|
{
|
||||||
UvAsyncSend();
|
_onPostTcs = new TaskCompletionSource<object>();
|
||||||
|
_completedOnPostTcs = false;
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
PostCount++;
|
||||||
Monitor.Exit(_postLock);
|
|
||||||
}
|
_loopWh.Set();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Task.Run(() =>
|
|
||||||
{
|
|
||||||
lock (_postLock)
|
|
||||||
{
|
|
||||||
UvAsyncSend();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -83,13 +70,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests.TestHelpers
|
||||||
|
|
||||||
lock (_postLock)
|
lock (_postLock)
|
||||||
{
|
{
|
||||||
_sendCalled = false;
|
|
||||||
_loopWh.Reset();
|
_loopWh.Reset();
|
||||||
_onPost(_postHandle.InternalGetHandle());
|
}
|
||||||
|
|
||||||
|
_onPost(_postHandle.InternalGetHandle());
|
||||||
|
|
||||||
|
lock (_postLock)
|
||||||
|
{
|
||||||
// Allow the loop to be run again before completing
|
// Allow the loop to be run again before completing
|
||||||
// _onPostTcs given a nested uv_async_send call.
|
// _onPostTcs given a nested uv_async_send call.
|
||||||
if (!_sendCalled)
|
if (!_loopWh.IsSet)
|
||||||
{
|
{
|
||||||
// Ensure any subsequent calls to uv_async_send
|
// Ensure any subsequent calls to uv_async_send
|
||||||
// create a new _onPostTcs to be completed.
|
// create a new _onPostTcs to be completed.
|
||||||
|
|
@ -171,19 +161,5 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests.TestHelpers
|
||||||
{
|
{
|
||||||
return OnWrite(handle, nbufs, status => cb(req.InternalGetHandle(), status));
|
return OnWrite(handle, nbufs, status => cb(req.InternalGetHandle(), status));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UvAsyncSend()
|
|
||||||
{
|
|
||||||
if (_completedOnPostTcs)
|
|
||||||
{
|
|
||||||
_onPostTcs = new TaskCompletionSource<object>();
|
|
||||||
_completedOnPostTcs = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PostCount++;
|
|
||||||
|
|
||||||
_sendCalled = true;
|
|
||||||
_loopWh.Set();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue