## Why is this an issue?

To prevent potential deadlocks in an application, it is crucial to release any locks that are acquired within a method along all possible execution paths.

Failing to release locks properly can lead to potential deadlocks, where the lock might not be released, causing issues in the application.

This rule specifically focuses on tracking the following types from the `System.Threading` namespace:

- `Monitor`
- `Mutex`
- `ReaderWriterLock`
- `ReaderWriterLockSlim`
- `SpinLock`

An issue is reported when a lock is acquired within a method but not released on all paths.

### Exceptions

If the lock is never released within the method, no issue is raised, assuming that the callers will handle the release.

## How to fix it

To make sure that a lock is always released correctly, you can follow one of these two methods:

- Use a `SyncLock` statement with your lock object.
- Use a `Try-Finally` statement and put the release of your lock object within a `Finally` block.

### Code examples

#### Noncompliant code example

    Class Example
        Private obj As Object = New Object()

        Public Sub DoSomethingWithMonitor()
            Monitor.Enter(obj) ' Noncompliant: not all paths release the lock

            If IsInitialized() Then
                ' ...
                Monitor.Exit(obj)
            End If
        End Sub
    End Class

    Class Example
        Private lockObj As ReaderWriterLockSlim = New ReaderWriterLockSlim()

        Public Sub DoSomethingWithReaderWriteLockSlim()
            lockObj.EnterReadLock() ' Noncompliant: not all paths release the lock
            If IsInitialized() Then
                ' ...
                lockObj.ExitReadLock()
            End If
        End Sub
    End Class

#### Compliant solution

    Class Example
        Private obj As Object = New Object()

        Public Sub DoSomethingWithMonitor()
            SyncLock obj ' Compliant: the lock will be released at the end of the SyncLock block
                If IsInitialized() Then
                    ' ...
                End If
            End SyncLock
        End Sub
    End Class

    Class Example
        Private lockObj As ReaderWriterLockSlim = New ReaderWriterLockSlim()

        Public Sub DoSomethingWithReaderWriteLockSlim()
            lockObj.EnterReadLock() ' Compliant: the lock will be released in the finally block

            Try
                If IsInitialized() Then
                    ' ...
                End If
            Finally
                lockObj.ExitReadLock()
            End Try
        End Sub
    End Class

## Resources

- Synchronization of access to a shared resource
- CWE - CWE-459 - Incomplete Cleanup
- `SyncLock` statement
- `Finally` block