Avoid Empty Critical Sections
ID |
go.avoid_empty_critical_sections |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Go |
Tags |
reliability, suspicious |
Description
Reports a mutex Lock() immediately followed by an Unlock() on the same receiver with
nothing in between — either as two adjacent statements (mu.Lock(); mu.Unlock()) or as a
lock followed immediately by a deferred unlock (mu.Lock(); defer mu.Unlock()).
Rationale
An empty critical section acquires and releases the lock without touching any shared state, so
it protects nothing and is pure synchronization overhead. It is almost always leftover from
deleted code, or a guard that was placed on the wrong statement. Only a Lock/Unlock pair on
the same receiver is flagged; a lock and an unlock on different receivers, or any statement
between them, is left alone.
c.mu.Lock() // FLAW — released immediately, nothing protected
c.mu.Unlock()
c.mu.Lock() // OK — guards a real update
c.n++
c.mu.Unlock()
Remediation
Move the work that must be protected inside the critical section, or delete the empty lock/unlock pair entirely.