I’ve been noticing a strange thing for a while on Windows 8/8.1 and the equivalent server versions. The issue occurs when I’m using a Slim Reader/Writer Lock (SRWL) exclusively in exclusive mode (as a replacement for critical sections). What happens is, when a thread that has just unlocked a SRWL exits cleanly, immediately after unlocking the lock, sometimes threads that are waiting on the lock do not get woken and none of them acquire the lock.
At first I spent ages thinking that this was some kind of subtle bug in my LockExplorer tool as initially the problem only manifested itself during test runs that were using LockExplorer to detect potential deadlocks. Recently, however, I’ve been seeing the identical problem in normal programs being run with no clever lock instrumentation going on.
I still think it’s more likely my bug than the operating system’s but I recently found this Knowledge Base article, #2582203, “A process that is being terminated stops responding in Windows 7 or in Windows Server 2008 R2” which says “This issue occurs because the main thread that terminates the process tries to reactivate another thread that was terminated when the thread released an SRW lock. This race condition causes the process to stop responding.”. This sounds suspiciously like the problem that I’m seeing, though not exactly.
The problem I see is that other threads waiting on the SWRL don’t get notified that the lock is now unlocked. This locks my program up during shutdown purely because I have code that waits for these threads to exit cleanly and they can’t as they’re waiting on an unlocked SRWL. It’s not a deadlocked attempt at recursive SWRL acquisition as I have debug code in my wrapper class which detects such behaviour. It’s not an orphaned locked SRWL as breaking the hung process into the debugger and immediately continuing it causes one of the threads that’s blocking on the lock to immediately acquire it and continue.
I haven’t applied the hotfix yet, partly because my systems are Win 8 rather than Win 7 and partly because I’m not yet convinced that this is the issue.
As a work around I’ve added a call to Sleep at the point where my thread class allows a thread to exit. This seems to reduce the instances of the problem, which leads me to believe it’s a race condition of some kind.