From d4a64313c3f83c80ae97af37af20f874b4abb6dd Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 27 Apr 2017 11:28:44 -0500 Subject: [PATCH] Add workaround for AsyncSemaphore disposal problems This is a workaround for #18563. See #19042 for a follow-up task to remove this workaround. --- .../Remote/InProcRemostHostClient.cs | 2 +- .../Core/Next/Remote/JsonRpcClient.cs | 2 +- .../Core/Next/Remote/JsonRpcMessageHandler.cs | 29 +++++++++++++++++++ .../Next/Remote/ServiceHubRemoteHostClient.cs | 2 +- .../Next/ServicesVisualStudio.Next.csproj | 1 + .../Remote/Razor/RazorServiceHub.csproj | 3 ++ .../Remote/ServiceHub/ServiceHub.csproj | 3 ++ .../Shared/ServiceHubServiceBase.cs | 3 +- 8 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 src/VisualStudio/Core/Next/Remote/JsonRpcMessageHandler.cs diff --git a/src/EditorFeatures/TestUtilities/Remote/InProcRemostHostClient.cs b/src/EditorFeatures/TestUtilities/Remote/InProcRemostHostClient.cs index 26bdab817b7..c185f1bfa27 100644 --- a/src/EditorFeatures/TestUtilities/Remote/InProcRemostHostClient.cs +++ b/src/EditorFeatures/TestUtilities/Remote/InProcRemostHostClient.cs @@ -48,7 +48,7 @@ public static async Task CreateAsync(Workspace workspace, bool { _inprocServices = inprocServices; - _rpc = new JsonRpc(stream, stream, target: this); + _rpc = new JsonRpc(new JsonRpcMessageHandler(stream, stream), target: this); _rpc.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance); // handle disconnected situation diff --git a/src/VisualStudio/Core/Next/Remote/JsonRpcClient.cs b/src/VisualStudio/Core/Next/Remote/JsonRpcClient.cs index ca65856a655..42e1d7d427e 100644 --- a/src/VisualStudio/Core/Next/Remote/JsonRpcClient.cs +++ b/src/VisualStudio/Core/Next/Remote/JsonRpcClient.cs @@ -28,7 +28,7 @@ internal class JsonRpcClient : IDisposable var target = useThisAsCallback ? this : callbackTarget; _cancellationToken = cancellationToken; - _rpc = new JsonRpc(stream, stream, target); + _rpc = new JsonRpc(new JsonRpcMessageHandler(stream, stream), target); _rpc.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance); _rpc.Disconnected += OnDisconnected; diff --git a/src/VisualStudio/Core/Next/Remote/JsonRpcMessageHandler.cs b/src/VisualStudio/Core/Next/Remote/JsonRpcMessageHandler.cs new file mode 100644 index 00000000000..81eb5c574a3 --- /dev/null +++ b/src/VisualStudio/Core/Next/Remote/JsonRpcMessageHandler.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.IO; +using StreamJsonRpc; + +namespace Microsoft.VisualStudio.LanguageServices.Remote +{ + // This is a workaround for a limitation in vs-threading. + // https://github.com/dotnet/roslyn/issues/19042 + internal class JsonRpcMessageHandler : HeaderDelimitedMessageHandler + { + public JsonRpcMessageHandler(Stream sendingStream, Stream receivingStream) + : base(sendingStream, receivingStream) + { + } + + protected override void Dispose(bool disposing) + { + // Do not call base.Dispose. We do not want the AsyncSemaphore instances to be disposed due to a race + // condition. + + if (disposing) + { + ReceivingStream?.Dispose(); + SendingStream?.Dispose(); + } + } + } +} diff --git a/src/VisualStudio/Core/Next/Remote/ServiceHubRemoteHostClient.cs b/src/VisualStudio/Core/Next/Remote/ServiceHubRemoteHostClient.cs index 84f2348e5c5..a4b9e2a3d96 100644 --- a/src/VisualStudio/Core/Next/Remote/ServiceHubRemoteHostClient.cs +++ b/src/VisualStudio/Core/Next/Remote/ServiceHubRemoteHostClient.cs @@ -106,7 +106,7 @@ private static async Task RegisterWorkspaceHostAsync(Workspace workspace, Remote _hostGroup = hostGroup; _timeout = TimeSpan.FromMilliseconds(workspace.Options.GetOption(RemoteHostOptions.RequestServiceTimeoutInMS)); - _rpc = new JsonRpc(stream, stream, target: this); + _rpc = new JsonRpc(new JsonRpcMessageHandler(stream, stream), target: this); _rpc.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance); // handle disconnected situation diff --git a/src/VisualStudio/Core/Next/ServicesVisualStudio.Next.csproj b/src/VisualStudio/Core/Next/ServicesVisualStudio.Next.csproj index cb72409950a..d9ae8c0a7b6 100644 --- a/src/VisualStudio/Core/Next/ServicesVisualStudio.Next.csproj +++ b/src/VisualStudio/Core/Next/ServicesVisualStudio.Next.csproj @@ -105,6 +105,7 @@ + diff --git a/src/Workspaces/Remote/Razor/RazorServiceHub.csproj b/src/Workspaces/Remote/Razor/RazorServiceHub.csproj index 6e29caea382..4351aeb3493 100644 --- a/src/Workspaces/Remote/Razor/RazorServiceHub.csproj +++ b/src/Workspaces/Remote/Razor/RazorServiceHub.csproj @@ -44,6 +44,9 @@ + + Shared\JsonRpcMessageHandler.cs + Shared\RoslynJsonConverter.cs diff --git a/src/Workspaces/Remote/ServiceHub/ServiceHub.csproj b/src/Workspaces/Remote/ServiceHub/ServiceHub.csproj index 26d66f271df..1ab54a50d29 100644 --- a/src/Workspaces/Remote/ServiceHub/ServiceHub.csproj +++ b/src/Workspaces/Remote/ServiceHub/ServiceHub.csproj @@ -60,6 +60,9 @@ Telemetry\VSTelemetryLogger.cs + + Shared\JsonRpcMessageHandler.cs + diff --git a/src/Workspaces/Remote/ServiceHub/Shared/ServiceHubServiceBase.cs b/src/Workspaces/Remote/ServiceHub/Shared/ServiceHubServiceBase.cs index 44f7c95c5f0..36336263409 100644 --- a/src/Workspaces/Remote/ServiceHub/Shared/ServiceHubServiceBase.cs +++ b/src/Workspaces/Remote/ServiceHub/Shared/ServiceHubServiceBase.cs @@ -6,6 +6,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Options; +using Microsoft.VisualStudio.LanguageServices.Remote; using Roslyn.Utilities; using StreamJsonRpc; @@ -66,7 +67,7 @@ protected ServiceHubServiceBase(IServiceProvider serviceProvider, Stream stream) // due to this issue - https://github.com/dotnet/roslyn/issues/16900#issuecomment-277378950 // all sub type must explicitly start JsonRpc once everything is // setup - Rpc = new JsonRpc(stream, stream, this); + Rpc = new JsonRpc(new JsonRpcMessageHandler(stream, stream), this); Rpc.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance); Rpc.Disconnected += OnRpcDisconnected; } -- GitLab