A lock is held during a wait¶
ID: cs/locked-waitKind: problemSecurity severity: Severity: warningPrecision: highTags: - quality - reliability - concurrency - correctness - external/cwe/cwe-662 - external/cwe/cwe-833Query suites: - csharp-security-and-quality.qls
Click to see the query in the CodeQL repository
Holding a lock during a call toSystem.Threading.Monitor.Wait() can lead to performance problems or deadlock because the lock can prevent other threads from running. This can be caused by nesting the call toSystem.Threading.Monitor.Wait() in twolock statements, or by waiting on a different object to the one which is locked.
Synchronized methods (with the attribute[MethodImpl(MethodImplOptions.Synchronized)]) can also cause problems, because they are equivalent tolock(this) orlock(typeof(Class)).
Recommendation¶
Ensure that the call toSystem.Threading.Monitor.Wait() occurs within a singlelock statement and ensure that the argument toSystem.Threading.Monitor.Wait() matches the variable in thelock statement.
Example¶
The following example locks two variables,countLock andtextLock, then callsSystem.Threading.Monitor.Wait(). However for the duration ofWait(), the variablecountLock is locked, which deadlocks the program.
classMessage{readonlyObjectcountLock=newObject();readonlyObjecttextLock=newObject();intcount;stringtext;publicvoidPrint(){lock(countLock){lock(textLock){while(text==null)System.Threading.Monitor.Wait(textLock);System.Console.Out.WriteLine(text+"="+count);}}}publicstringText{set{lock(countLock){lock(textLock){++count;text=value;System.Threading.Monitor.Pulse(textLock);}}}}}
The problem can be fixed by moving thelock statement so thatcountLock is not locked for the duration of the wait.
classMessage{readonlyObjectcountLock=newObject();readonlyObjecttextLock=newObject();intcount;stringtext;publicvoidPrint(){lock(textLock){while(text==null)System.Threading.Monitor.Wait(textLock);lock(countLock)System.Console.Out.WriteLine(text+"="+count);}}publicstringText{set{lock(countLock){lock(textLock){++count;text=value;System.Threading.Monitor.Pulse(textLock);}}}}}
References¶
MSDN, C# Reference:lock Statement.
Common Weakness Enumeration:CWE-662.
Common Weakness Enumeration:CWE-833.