From 34d411c26c459b1ba72e427b3dd757449265de6f Mon Sep 17 00:00:00 2001 From: mary-georgiou-sonarsource Date: Tue, 29 Oct 2024 13:58:18 +0000 Subject: [PATCH 1/8] Create rule S7133 --- rules/S7133/csharp/metadata.json | 25 ++++++++++++++++++ rules/S7133/csharp/rule.adoc | 44 ++++++++++++++++++++++++++++++++ rules/S7133/metadata.json | 2 ++ 3 files changed, 71 insertions(+) create mode 100644 rules/S7133/csharp/metadata.json create mode 100644 rules/S7133/csharp/rule.adoc create mode 100644 rules/S7133/metadata.json diff --git a/rules/S7133/csharp/metadata.json b/rules/S7133/csharp/metadata.json new file mode 100644 index 00000000000..b879954e21b --- /dev/null +++ b/rules/S7133/csharp/metadata.json @@ -0,0 +1,25 @@ +{ + "title": "FIXME", + "type": "CODE_SMELL", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + ], + "defaultSeverity": "Major", + "ruleSpecification": "RSPEC-7133", + "sqKey": "S7133", + "scope": "All", + "defaultQualityProfiles": ["Sonar way"], + "quickfix": "unknown", + "code": { + "impacts": { + "MAINTAINABILITY": "HIGH", + "RELIABILITY": "MEDIUM", + "SECURITY": "LOW" + }, + "attribute": "CONVENTIONAL" + } +} diff --git a/rules/S7133/csharp/rule.adoc b/rules/S7133/csharp/rule.adoc new file mode 100644 index 00000000000..e2c7df430f3 --- /dev/null +++ b/rules/S7133/csharp/rule.adoc @@ -0,0 +1,44 @@ +FIXME: add a description + +// If you want to factorize the description uncomment the following line and create the file. +//include::../description.adoc[] + +== Why is this an issue? + +FIXME: remove the unused optional headers (that are commented out) + +//=== What is the potential impact? + +== How to fix it +//== How to fix it in FRAMEWORK NAME + +=== Code examples + +==== Noncompliant code example + +[source,csharp,diff-id=1,diff-type=noncompliant] +---- +FIXME +---- + +==== Compliant solution + +[source,csharp,diff-id=1,diff-type=compliant] +---- +FIXME +---- + +//=== How does this work? + +//=== Pitfalls + +//=== Going the extra mile + + +//== Resources +//=== Documentation +//=== Articles & blog posts +//=== Conference presentations +//=== Standards +//=== External coding guidelines +//=== Benchmarks diff --git a/rules/S7133/metadata.json b/rules/S7133/metadata.json new file mode 100644 index 00000000000..2c63c085104 --- /dev/null +++ b/rules/S7133/metadata.json @@ -0,0 +1,2 @@ +{ +} From b6185b94188916b86329617b019c6ba4a2e217be Mon Sep 17 00:00:00 2001 From: Mary Georgiou <89914005+mary-georgiou-sonarsource@users.noreply.github.com> Date: Wed, 30 Oct 2024 15:43:07 +0100 Subject: [PATCH 2/8] first draft --- rules/S7133/csharp/rule.adoc | 110 ++++++++++++++++++++++++++++------- 1 file changed, 89 insertions(+), 21 deletions(-) diff --git a/rules/S7133/csharp/rule.adoc b/rules/S7133/csharp/rule.adoc index e2c7df430f3..18156879bf6 100644 --- a/rules/S7133/csharp/rule.adoc +++ b/rules/S7133/csharp/rule.adoc @@ -1,16 +1,26 @@ -FIXME: add a description -// If you want to factorize the description uncomment the following line and create the file. -//include::../description.adoc[] +When you acquire a lock you should also release it in the same method. -== Why is this an issue? +This rule raises if you acquire a lock with one of the following methods and you do not release it. + +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirewriterlock[ReaderWriterLock.AcquireWriterLock] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirereaderlock[ReaderWriterLock.AcquireReaderLock] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterwritelock[ReaderWriterLockSlim.EnterWriteLock] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterwritelock[ReaderWriterLockSlim.TryEnterWriteLock] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterreadlock[ReaderWriterLockSlim.EnterReadLock] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterreadlock[ReaderWriterLockSlim.TryEnterReadLock] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterupgradeablereadlock[ReaderWriterLockSlim.EnterUpgradeableReadLock] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterupgradeablereadlock[ReaderWriterLockSlim.TryEnterUpgradeableReadLock] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock.enter[SpinLock.Enter] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock.tryente[SpinLock.TryEnter] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.monitor.enter[Monitor.Enter] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.monitor.enter[Monitor.TryEnter] -FIXME: remove the unused optional headers (that are commented out) -//=== What is the potential impact? -== How to fix it -//== How to fix it in FRAMEWORK NAME +== Why is this an issue? +Not releasing a lock in the same method where you acquire it makes the code less clear and less easy to maintain. You are also introducing the risk of not releasing a lock at all +which can lead to deadlocks or exceptions. === Code examples @@ -18,27 +28,85 @@ FIXME: remove the unused optional headers (that are commented out) [source,csharp,diff-id=1,diff-type=noncompliant] ---- -FIXME +class Example +{ + private static ReaderWriterLock rwLock = new ReaderWriterLock(); + private static int sharedResource = 0; + + static void Writer() + { + try + { + rwLock.AcquireWriterLock(2000); // Noncompliant + sharedResource++; + } + finally + { + Reader(); + } + } + + static void Reader() + { + try + { + MethodThatMightThrow(); // If this method throws an exception the writer lock will never be released + rwLock.ReleaseWriterLock(); + rwLock.AcquireReaderLock(2000); + Console.WriteLine(sharedResource); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } +} ---- ==== Compliant solution [source,csharp,diff-id=1,diff-type=compliant] ---- -FIXME ----- +class Example +{ + private static ReaderWriterLock rwLock = new ReaderWriterLock(); + private static int sharedResource = 0; -//=== How does this work? + static void Writer() + { + try + { + rwLock.AcquireWriterLock(2000); // Compliant + sharedResource++; + } + finally + { + rwLock.ReleaseWriterLock(); + Reader(); + } + } -//=== Pitfalls + static void Reader() + { + try + { + MethodThatMightThrow(); // If this method throws an exception the writer lock will never be released + rwLock.AcquireReaderLock(2000); + Console.WriteLine(sharedResource); + } + finally + { + rwLock.ReleaseReaderLock(); + } + } +} +---- -//=== Going the extra mile +== Resources +=== Documentation -//== Resources -//=== Documentation -//=== Articles & blog posts -//=== Conference presentations -//=== Standards -//=== External coding guidelines -//=== Benchmarks +* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock[ReaderWriterLock Class] +* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim[ReaderWriterLockSlim Classs] +* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock[Spinlock Struct] +* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.monitor[Monitor Classs] From d7bd5b166525f944599697fb5cea9970dffbb4b5 Mon Sep 17 00:00:00 2001 From: Mary Georgiou <89914005+mary-georgiou-sonarsource@users.noreply.github.com> Date: Wed, 30 Oct 2024 15:52:17 +0100 Subject: [PATCH 3/8] metadata --- rules/S7133/csharp/metadata.json | 10 ++++------ rules/S7133/csharp/rule.adoc | 2 ++ rules/S7133/message.adoc | 4 ++++ rules/S7133/rspecator.adoc | 7 +++++++ 4 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 rules/S7133/message.adoc create mode 100644 rules/S7133/rspecator.adoc diff --git a/rules/S7133/csharp/metadata.json b/rules/S7133/csharp/metadata.json index b879954e21b..7f560e6775b 100644 --- a/rules/S7133/csharp/metadata.json +++ b/rules/S7133/csharp/metadata.json @@ -1,6 +1,6 @@ { - "title": "FIXME", - "type": "CODE_SMELL", + "title": "Locks should be released within the same method", + "type": "BUG", "status": "ready", "remediation": { "func": "Constant\/Issue", @@ -13,12 +13,10 @@ "sqKey": "S7133", "scope": "All", "defaultQualityProfiles": ["Sonar way"], - "quickfix": "unknown", + "quickfix": "targeted", "code": { "impacts": { - "MAINTAINABILITY": "HIGH", - "RELIABILITY": "MEDIUM", - "SECURITY": "LOW" + "RELIABILITY": "HIGH" }, "attribute": "CONVENTIONAL" } diff --git a/rules/S7133/csharp/rule.adoc b/rules/S7133/csharp/rule.adoc index 18156879bf6..f5786cf4a06 100644 --- a/rules/S7133/csharp/rule.adoc +++ b/rules/S7133/csharp/rule.adoc @@ -110,3 +110,5 @@ class Example * Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim[ReaderWriterLockSlim Classs] * Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock[Spinlock Struct] * Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.monitor[Monitor Classs] + +include::../rspecator.adoc[] \ No newline at end of file diff --git a/rules/S7133/message.adoc b/rules/S7133/message.adoc new file mode 100644 index 00000000000..1433517ee78 --- /dev/null +++ b/rules/S7133/message.adoc @@ -0,0 +1,4 @@ +=== Message + +You should release this lock in the same method. + diff --git a/rules/S7133/rspecator.adoc b/rules/S7133/rspecator.adoc new file mode 100644 index 00000000000..769cd80813f --- /dev/null +++ b/rules/S7133/rspecator.adoc @@ -0,0 +1,7 @@ +ifdef::env-github,rspecator-view[] + +''' +== Implementation Specification +(visible only on this page) + +include::message.adoc[] From 1a81adcb676d29736683c4c20efa6cdb942702d2 Mon Sep 17 00:00:00 2001 From: Mary Georgiou <89914005+mary-georgiou-sonarsource@users.noreply.github.com> Date: Wed, 30 Oct 2024 15:56:35 +0100 Subject: [PATCH 4/8] to amend --- rules/S7133/csharp/rule.adoc | 14 ++++++-------- rules/S7133/rspecator.adoc | 2 ++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/rules/S7133/csharp/rule.adoc b/rules/S7133/csharp/rule.adoc index f5786cf4a06..add5f8d00bc 100644 --- a/rules/S7133/csharp/rule.adoc +++ b/rules/S7133/csharp/rule.adoc @@ -1,7 +1,4 @@ - -When you acquire a lock you should also release it in the same method. - -This rule raises if you acquire a lock with one of the following methods and you do not release it. +This rule raises if you acquire a lock with one of the following methods, and do not release it within the same method. * https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirewriterlock[ReaderWriterLock.AcquireWriterLock] * https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirereaderlock[ReaderWriterLock.AcquireReaderLock] @@ -19,8 +16,9 @@ This rule raises if you acquire a lock with one of the following methods and you == Why is this an issue? -Not releasing a lock in the same method where you acquire it makes the code less clear and less easy to maintain. You are also introducing the risk of not releasing a lock at all -which can lead to deadlocks or exceptions. + +Not releasing a lock in the same method where you acquire it, and releasing in another one, makes the code less clear and less easy to maintain. You are also introducing the risk of not releasing a lock at all which can lead to deadlocks or exceptions. + === Code examples @@ -37,7 +35,7 @@ class Example { try { - rwLock.AcquireWriterLock(2000); // Noncompliant + rwLock.AcquireWriterLock(2000); // Noncompliant, lock is released in another method sharedResource++; } finally @@ -90,7 +88,7 @@ class Example { try { - MethodThatMightThrow(); // If this method throws an exception the writer lock will never be released + MethodThatMightThrow(); rwLock.AcquireReaderLock(2000); Console.WriteLine(sharedResource); } diff --git a/rules/S7133/rspecator.adoc b/rules/S7133/rspecator.adoc index 769cd80813f..a791a6b354e 100644 --- a/rules/S7133/rspecator.adoc +++ b/rules/S7133/rspecator.adoc @@ -5,3 +5,5 @@ ifdef::env-github,rspecator-view[] (visible only on this page) include::message.adoc[] + +endif::env-github,rspecator-view[] From 453fe4f83078b5fc6765d6445d8b80539667f948 Mon Sep 17 00:00:00 2001 From: Mary Georgiou <89914005+mary-georgiou-sonarsource@users.noreply.github.com> Date: Fri, 1 Nov 2024 09:02:04 +0100 Subject: [PATCH 5/8] review 1 --- rules/S7133/csharp/rule.adoc | 65 +++++++++--------------------------- 1 file changed, 16 insertions(+), 49 deletions(-) diff --git a/rules/S7133/csharp/rule.adoc b/rules/S7133/csharp/rule.adoc index add5f8d00bc..b027057425e 100644 --- a/rules/S7133/csharp/rule.adoc +++ b/rules/S7133/csharp/rule.adoc @@ -9,15 +9,15 @@ This rule raises if you acquire a lock with one of the following methods, and do * https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterupgradeablereadlock[ReaderWriterLockSlim.EnterUpgradeableReadLock] * https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterupgradeablereadlock[ReaderWriterLockSlim.TryEnterUpgradeableReadLock] * https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock.enter[SpinLock.Enter] -* https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock.tryente[SpinLock.TryEnter] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock.tryenter[SpinLock.TryEnter] * https://learn.microsoft.com/en-us/dotnet/api/system.threading.monitor.enter[Monitor.Enter] -* https://learn.microsoft.com/en-us/dotnet/api/system.threading.monitor.enter[Monitor.TryEnter] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.monitor.tryenter[Monitor.TryEnter] == Why is this an issue? -Not releasing a lock in the same method where you acquire it, and releasing in another one, makes the code less clear and less easy to maintain. You are also introducing the risk of not releasing a lock at all which can lead to deadlocks or exceptions. +Not releasing a lock in the same method where you acquire it, and releasing in another one, makes the code less clear and harder to maintain. You are also introducing the risk of not releasing a lock at all which can lead to deadlocks or exceptions. === Code examples @@ -29,35 +29,19 @@ Not releasing a lock in the same method where you acquire it, and releasing in a class Example { private static ReaderWriterLock rwLock = new ReaderWriterLock(); - private static int sharedResource = 0; - static void Writer() + public void DoSomething() { - try - { - rwLock.AcquireWriterLock(2000); // Noncompliant, lock is released in another method - sharedResource++; - } - finally - { - Reader(); - } + WriteLock(); // Noncompliant + ReleaseLock(); } - static void Reader() - { - try - { - MethodThatMightThrow(); // If this method throws an exception the writer lock will never be released - rwLock.ReleaseWriterLock(); - rwLock.AcquireReaderLock(2000); - Console.WriteLine(sharedResource); - } - finally - { - rwLock.ReleaseReaderLock(); - } - } + public void WriteLock() => + rwLock.AcquireWriterLock(2000); + + public void ReleaseLock() => + rwLock.ReleaseWriterLock(); + } ---- @@ -68,33 +52,16 @@ class Example class Example { private static ReaderWriterLock rwLock = new ReaderWriterLock(); - private static int sharedResource = 0; - static void Writer() + public void DoSomething() { try { - rwLock.AcquireWriterLock(2000); // Compliant - sharedResource++; + rwLock.AcquireWriterLock(2000); } - finally + finally { rwLock.ReleaseWriterLock(); - Reader(); - } - } - - static void Reader() - { - try - { - MethodThatMightThrow(); - rwLock.AcquireReaderLock(2000); - Console.WriteLine(sharedResource); - } - finally - { - rwLock.ReleaseReaderLock(); } } } @@ -106,7 +73,7 @@ class Example * Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock[ReaderWriterLock Class] * Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim[ReaderWriterLockSlim Classs] -* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock[Spinlock Struct] +* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock[SpinLock Struct] * Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.threading.monitor[Monitor Classs] include::../rspecator.adoc[] \ No newline at end of file From b34f2e7c93c5532dfb62d84c70f8bd625a3ee5cc Mon Sep 17 00:00:00 2001 From: Mary Georgiou <89914005+mary-georgiou-sonarsource@users.noreply.github.com> Date: Fri, 1 Nov 2024 10:00:54 +0100 Subject: [PATCH 6/8] update cpde example --- rules/S7133/csharp/rule.adoc | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/rules/S7133/csharp/rule.adoc b/rules/S7133/csharp/rule.adoc index b027057425e..407b6e978ad 100644 --- a/rules/S7133/csharp/rule.adoc +++ b/rules/S7133/csharp/rule.adoc @@ -30,18 +30,16 @@ class Example { private static ReaderWriterLock rwLock = new ReaderWriterLock(); - public void DoSomething() + public void AcquireWriterLock() => + rwLock.AcquireWriterLock(2000); // Noncompliant, as the lock release is on the callers responsibilty + + public void DoSomething() { - WriteLock(); // Noncompliant - ReleaseLock(); + // ... } - public void WriteLock() => - rwLock.AcquireWriterLock(2000); - - public void ReleaseLock() => + public void ReleaseWriterLock() => rwLock.ReleaseWriterLock(); - } ---- @@ -55,9 +53,10 @@ class Example public void DoSomething() { + rwLock.AcquireWriterLock(2000); // Compliant, locks are released in the same method try { - rwLock.AcquireWriterLock(2000); + // ... } finally { From f85444ab2de56d9895c26e4d7f8d02e2975d789a Mon Sep 17 00:00:00 2001 From: Mary Georgiou <89914005+mary-georgiou-sonarsource@users.noreply.github.com> Date: Fri, 1 Nov 2024 10:35:04 +0100 Subject: [PATCH 7/8] nitpicks --- rules/S7133/csharp/rule.adoc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/rules/S7133/csharp/rule.adoc b/rules/S7133/csharp/rule.adoc index 407b6e978ad..0f8b6e56d77 100644 --- a/rules/S7133/csharp/rule.adoc +++ b/rules/S7133/csharp/rule.adoc @@ -1,13 +1,13 @@ This rule raises if you acquire a lock with one of the following methods, and do not release it within the same method. -* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirewriterlock[ReaderWriterLock.AcquireWriterLock] * https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirereaderlock[ReaderWriterLock.AcquireReaderLock] -* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterwritelock[ReaderWriterLockSlim.EnterWriteLock] -* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterwritelock[ReaderWriterLockSlim.TryEnterWriteLock] * https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterreadlock[ReaderWriterLockSlim.EnterReadLock] * https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterreadlock[ReaderWriterLockSlim.TryEnterReadLock] -* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterupgradeablereadlock[ReaderWriterLockSlim.EnterUpgradeableReadLock] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirewriterlock[ReaderWriterLock.AcquireWriterLock] * https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterupgradeablereadlock[ReaderWriterLockSlim.TryEnterUpgradeableReadLock] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterupgradeablereadlock[ReaderWriterLockSlim.EnterUpgradeableReadLock] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterwritelock[ReaderWriterLockSlim.EnterWriteLock] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterwritelock[ReaderWriterLockSlim.TryEnterWriteLock] * https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock.enter[SpinLock.Enter] * https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock.tryenter[SpinLock.TryEnter] * https://learn.microsoft.com/en-us/dotnet/api/system.threading.monitor.enter[Monitor.Enter] @@ -26,9 +26,9 @@ Not releasing a lock in the same method where you acquire it, and releasing in a [source,csharp,diff-id=1,diff-type=noncompliant] ---- -class Example +public class Example { - private static ReaderWriterLock rwLock = new ReaderWriterLock(); + private static ReaderWriterLock rwLock = new(); public void AcquireWriterLock() => rwLock.AcquireWriterLock(2000); // Noncompliant, as the lock release is on the callers responsibilty @@ -47,9 +47,9 @@ class Example [source,csharp,diff-id=1,diff-type=compliant] ---- -class Example +public class Example { - private static ReaderWriterLock rwLock = new ReaderWriterLock(); + private static ReaderWriterLock rwLock = new(); public void DoSomething() { From ece996d70f47b4f48c07b4a7aba0600c772ea13f Mon Sep 17 00:00:00 2001 From: Mary Georgiou <89914005+mary-georgiou-sonarsource@users.noreply.github.com> Date: Fri, 1 Nov 2024 11:20:43 +0100 Subject: [PATCH 8/8] re-arrange --- rules/S7133/csharp/rule.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/S7133/csharp/rule.adoc b/rules/S7133/csharp/rule.adoc index 0f8b6e56d77..c95aa312906 100644 --- a/rules/S7133/csharp/rule.adoc +++ b/rules/S7133/csharp/rule.adoc @@ -1,11 +1,11 @@ This rule raises if you acquire a lock with one of the following methods, and do not release it within the same method. * https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirereaderlock[ReaderWriterLock.AcquireReaderLock] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirewriterlock[ReaderWriterLock.AcquireWriterLock] * https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterreadlock[ReaderWriterLockSlim.EnterReadLock] +* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterupgradeablereadlock[ReaderWriterLockSlim.EnterUpgradeableReadLock] * https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterreadlock[ReaderWriterLockSlim.TryEnterReadLock] -* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock.acquirewriterlock[ReaderWriterLock.AcquireWriterLock] * https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterupgradeablereadlock[ReaderWriterLockSlim.TryEnterUpgradeableReadLock] -* https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterupgradeablereadlock[ReaderWriterLockSlim.EnterUpgradeableReadLock] * https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.enterwritelock[ReaderWriterLockSlim.EnterWriteLock] * https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim.tryenterwritelock[ReaderWriterLockSlim.TryEnterWriteLock] * https://learn.microsoft.com/en-us/dotnet/api/system.threading.spinlock.enter[SpinLock.Enter]