SpinLock Readonly
ID |
csharp.spinlock_readonly |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
CSharp |
Tags |
concurrency, reliability |
Description
Reports fields whose type is SpinLock and which are declared readonly. Because
SpinLock is a mutable value type, the readonly modifier forces every access to
return a defensive copy and the lock no longer synchronises anything.
Rationale
SpinLock is implemented as a mutable struct. The lock state is stored inside the
struct value itself. When the field that holds the SpinLock is readonly, the
compiler copies the struct on every member access, so Enter is called on one copy
and Exit on another. The threads believe they are synchronising but in reality each
one sees its own unrelated lock state and the lock is silently broken.
using System.Threading;
public class Worker
{
private readonly SpinLock badSpin = new SpinLock(); // FLAW — each access copies
private SpinLock goodSpin = new SpinLock(); // OK — mutable backing field
public void DoWork()
{
bool taken = false;
goodSpin.Enter(ref taken);
try { /* ... */ }
finally { if (taken) goodSpin.Exit(); }
}
}