diff --git a/src/Compilers/Core/Portable/InternalUtilities/ReaderWriterLockSlimExtensions.cs b/src/Compilers/Core/Portable/InternalUtilities/ReaderWriterLockSlimExtensions.cs index 62e22dfb0b33d72cb6d5ce7524338916d5c6e7f0..952ad07d2610fc2b112d4d7c72ff8a4cdbfd837c 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/ReaderWriterLockSlimExtensions.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/ReaderWriterLockSlimExtensions.cs @@ -16,6 +16,7 @@ internal static ReadLockExiter DisposableRead(this ReaderWriterLockSlim @lock) return new ReadLockExiter(@lock); } + [NonCopyable] internal readonly struct ReadLockExiter : IDisposable { private readonly ReaderWriterLockSlim _lock; @@ -37,6 +38,7 @@ internal static UpgradeableReadLockExiter DisposableUpgradeableRead(this ReaderW return new UpgradeableReadLockExiter(@lock); } + [NonCopyable] internal readonly struct UpgradeableReadLockExiter : IDisposable { private readonly ReaderWriterLockSlim _lock; @@ -68,6 +70,7 @@ internal static WriteLockExiter DisposableWrite(this ReaderWriterLockSlim @lock) return new WriteLockExiter(@lock); } + [NonCopyable] internal readonly struct WriteLockExiter : IDisposable { private readonly ReaderWriterLockSlim _lock; diff --git a/src/Compilers/Core/Portable/InternalUtilities/SemaphoreSlimExtensions.cs b/src/Compilers/Core/Portable/InternalUtilities/SemaphoreSlimExtensions.cs index aca4f612bab849e5e31ef3523e1cb6cdc2b15e31..c06a9049d2bebcc620ccbb6d8a8e764b9886116f 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/SemaphoreSlimExtensions.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/SemaphoreSlimExtensions.cs @@ -25,6 +25,7 @@ public static async ValueTask DisposableWaitAsync(this Semaph return new SemaphoreDisposer(semaphore); } + [NonCopyable] internal struct SemaphoreDisposer : IDisposable { private readonly SemaphoreSlim _semaphore; diff --git a/src/Dependencies/PooledObjects/PooledDelegates.cs b/src/Dependencies/PooledObjects/PooledDelegates.cs index abc2036ea0bd653907254618e4bb2e6626ae1e9c..9bc47a206af14af9e1111c794d94a4ea9c909c3e 100644 --- a/src/Dependencies/PooledObjects/PooledDelegates.cs +++ b/src/Dependencies/PooledObjects/PooledDelegates.cs @@ -313,6 +313,7 @@ public static Releaser GetPooledAction(Action unboundAction, TArg ar /// omitted, the object will not be returned to the pool. The behavior of this type if is /// called multiple times is undefined. /// + [NonCopyable] public struct Releaser : IDisposable { private readonly Poolable _pooledObject; @@ -416,5 +417,10 @@ private sealed class FuncWithBoundArgument protected override Func Bind() => (arg1, arg2, arg3) => UnboundDelegate(arg1, arg2, arg3, Argument); } + + [AttributeUsage(AttributeTargets.Struct)] + private sealed class NonCopyableAttribute : Attribute + { + } } } diff --git a/src/Interactive/Host/Microsoft.CodeAnalysis.InteractiveHost.csproj b/src/Interactive/Host/Microsoft.CodeAnalysis.InteractiveHost.csproj index d9747dc75bec4cce6b0f19b5e77300cb0ee6ec7e..437c35b92d8e836542f72d9890b87b9ae65de161 100644 --- a/src/Interactive/Host/Microsoft.CodeAnalysis.InteractiveHost.csproj +++ b/src/Interactive/Host/Microsoft.CodeAnalysis.InteractiveHost.csproj @@ -37,6 +37,7 @@ + diff --git a/src/Workspaces/Core/Portable/Shared/Extensions/SafeHandleLease.cs b/src/Workspaces/Core/Portable/Shared/Extensions/SafeHandleLease.cs index 901fb2d3ec73d18a242debf15ab33f02c77ba9d4..68c390a6cc0010abd5581e082cd49cdfa40e29f8 100644 --- a/src/Workspaces/Core/Portable/Shared/Extensions/SafeHandleLease.cs +++ b/src/Workspaces/Core/Portable/Shared/Extensions/SafeHandleLease.cs @@ -6,6 +6,7 @@ using System; using System.Runtime.InteropServices; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Shared.Extensions { @@ -13,6 +14,7 @@ namespace Microsoft.CodeAnalysis.Shared.Extensions /// Represents a lease of a . /// /// + [NonCopyable] internal readonly struct SafeHandleLease : IDisposable { private readonly SafeHandle? _handle; diff --git a/src/Workspaces/Core/Portable/Storage/SQLite/Interop/SafeSqliteBlobHandle.cs b/src/Workspaces/Core/Portable/Storage/SQLite/Interop/SafeSqliteBlobHandle.cs index c7b9ab79c10b7791717718c46de0d148a3c8057e..e2e1b0618a0b286e53ae8e3e6d4e841c0513af6d 100644 --- a/src/Workspaces/Core/Portable/Storage/SQLite/Interop/SafeSqliteBlobHandle.cs +++ b/src/Workspaces/Core/Portable/Storage/SQLite/Interop/SafeSqliteBlobHandle.cs @@ -31,10 +31,16 @@ public sqlite3_blob DangerousGetWrapper() protected override bool ReleaseHandle() { - using var _ = _lease; - var result = (Result)raw.sqlite3_blob_close(_wrapper); - SetHandle(IntPtr.Zero); - return result == Result.OK; + try + { + var result = (Result)raw.sqlite3_blob_close(_wrapper); + SetHandle(IntPtr.Zero); + return result == Result.OK; + } + finally + { + _lease.Dispose(); + } } } } diff --git a/src/Workspaces/Core/Portable/Storage/SQLite/Interop/SafeSqliteStatementHandle.cs b/src/Workspaces/Core/Portable/Storage/SQLite/Interop/SafeSqliteStatementHandle.cs index b8b27f2883d8d7f859ba32e1bf02ef2f2628a9d1..1a30942fff3c2bd807658532e7488d591bf868b1 100644 --- a/src/Workspaces/Core/Portable/Storage/SQLite/Interop/SafeSqliteStatementHandle.cs +++ b/src/Workspaces/Core/Portable/Storage/SQLite/Interop/SafeSqliteStatementHandle.cs @@ -31,10 +31,16 @@ public sqlite3_stmt DangerousGetWrapper() protected override bool ReleaseHandle() { - using var _ = _lease; - var result = (Result)raw.sqlite3_finalize(_wrapper); - SetHandle(IntPtr.Zero); - return result == Result.OK; + try + { + var result = (Result)raw.sqlite3_finalize(_wrapper); + SetHandle(IntPtr.Zero); + return result == Result.OK; + } + finally + { + _lease.Dispose(); + } } } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems index 3bbc78457b7ae93d9492c6c74205e36c11b5733e..ec9732473e33f95dd16f0664a977c6f5ad4acae2 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems @@ -14,6 +14,7 @@ + diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/ObjectPools/PooledDisposer.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/ObjectPools/PooledDisposer.cs index a57e378d67be3f577344597aa2feaa4686394f64..337358e4cda92b6f61bd6502a9b81407d839d325 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/ObjectPools/PooledDisposer.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/ObjectPools/PooledDisposer.cs @@ -3,9 +3,11 @@ // See the LICENSE file in the project root for more information. using System; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.PooledObjects { + [NonCopyable] internal readonly struct PooledDisposer : IDisposable where TPoolable : class, IPooled {