From 040ea2e6b45b5909abe3c3b0e199ff6dd6136026 Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Thu, 18 Jan 2018 15:53:46 -0800 Subject: [PATCH] Fix MockLibuv.OnPostTask (#2260) Prevents UvWriteReq leaks in LibuvOutputConsumerTests --- .../TestHelpers/MockLibuv.cs | 52 +++++-------------- 1 file changed, 14 insertions(+), 38 deletions(-) diff --git a/test/Kestrel.Transport.Libuv.Tests/TestHelpers/MockLibuv.cs b/test/Kestrel.Transport.Libuv.Tests/TestHelpers/MockLibuv.cs index 4f334bcfea..6cb3f6917a 100644 --- a/test/Kestrel.Transport.Libuv.Tests/TestHelpers/MockLibuv.cs +++ b/test/Kestrel.Transport.Libuv.Tests/TestHelpers/MockLibuv.cs @@ -16,7 +16,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests.TestHelpers private readonly object _postLock = new object(); private TaskCompletionSource _onPostTcs = new TaskCompletionSource(); private bool _completedOnPostTcs; - private bool _sendCalled; private bool _stopLoop; private readonly ManualResetEventSlim _loopWh = new ManualResetEventSlim(); @@ -38,29 +37,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests.TestHelpers _uv_async_send = postHandle => { - // Attempt to run the async send logic inline; this should succeed most of the time. - // 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)) + lock (_postLock) { - try + if (_completedOnPostTcs) { - UvAsyncSend(); + _onPostTcs = new TaskCompletionSource(); + _completedOnPostTcs = false; } - finally - { - Monitor.Exit(_postLock); - } - } - else - { - Task.Run(() => - { - lock (_postLock) - { - UvAsyncSend(); - } - }); + + PostCount++; + + _loopWh.Set(); } return 0; @@ -83,13 +70,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests.TestHelpers lock (_postLock) { - _sendCalled = false; _loopWh.Reset(); - _onPost(_postHandle.InternalGetHandle()); + } + _onPost(_postHandle.InternalGetHandle()); + + lock (_postLock) + { // Allow the loop to be run again before completing // _onPostTcs given a nested uv_async_send call. - if (!_sendCalled) + if (!_loopWh.IsSet) { // Ensure any subsequent calls to uv_async_send // 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)); } - - private void UvAsyncSend() - { - if (_completedOnPostTcs) - { - _onPostTcs = new TaskCompletionSource(); - _completedOnPostTcs = false; - } - - PostCount++; - - _sendCalled = true; - _loopWh.Set(); - } } }