I'm trying to add some debug checking for a CRITICAL_SECTION unlocking code, and I tried the following:
...
if (m_pCritSect) {
ASSERT(m_pCritSect->OwningThread == GetCurrentThreadId());
LeaveCriticalSection(m_pCritSect);
}
}
From debugging CRITICAL_SECTIONS (With VS 2005, mostly on WindowsXP) I "know" that the value of OwningThread (member of the RTL_CRITICAL_SECTION structure defined in winnt.h) is the value of th ID of the thread holding the lock.
However thread IDs are represented by DWORD (typedef for unsigned long) values while this variable has type HANDLE (typedef for void*) requiring a the use of the reinterpret_cast forHandleToULong Macro from basetsd.h for the above code to work.
Even the MSDN docs state:
When the first thread calls the EnterCriticalSection routine, (...) OwningThread becomes the thread ID of the caller.
So why on earth is this defined as a HANDLE?
Edit Note: I found a statement where a poster suggests that the HANDLE / DWORD-Id mismatch is some known misfeature of some Windows internals. So maybe this is the case here too:
GetCurrentThreadId returns a DWORD, which I send up to the kernel in a message. PsLookupThreadByThreadId takes the thread Id in a HANDLE, ... ...
This is a known Windows API bug ("known" in that I talked to the relevant filter manager DEV about this, as it shows up in Filter Manager as well because of the I/O Manager API issue.) As long as you don't have more than a half billion