Lothar
Lothar

Reputation: 13067

Can i get the id of the thread which holds a CriticalSection?

I want to write a few asserts around a complicated multithreaded piece of code. Is there some way to do a

assert(GetCurrentThreadId() == ThreadOfCriticalSection(sec));

Upvotes: 3

Views: 894

Answers (3)

Leo Davidson
Leo Davidson

Reputation: 6133

If you want to do this properly I think you have use a wrapper object around your critical sections which will track which thread (if any) owns each CS in debug builds.

i.e. Rather than call EnterCriticalSection directly, you'd call a method on your wrapper which did the EnterCriticalSection and then, when it succeeded, stored GetCurrentThreadId in a DWORD which the asserts would check. Another method would zero that thread ID DWORD before calling LeaveCriticalSection.

(In release builds, the wrapper would probably omit the extra stuff and just call Enter/LeaveCriticalSection.)

As Casablanca points out, the owner thread ID is within the current CRITICAL_SECTION structure, so using a wrapper like I suggest would be storing redundant information. But, as Casablanca also points out, the CRITICAL_SECTION structure is not part of any API contract and could change. (In fact, it has changed in past Windows versions.)

Knowing the internal structure is useful for debugging but should not be used in production code.

So which method you use depends on how "proper" you want your solution to be. If you just want some temporary asserts for tracking down problems today, on the current version of Windows, then using the CRITICAL_SECTION fields directly seems reasonable to me. Just don't expect those asserts to be valid forever. If you want something that will last longer, use a wrapper.

(Another advantage of using a wrapper is that you'll get RAII. i.e. The wrapper's constructor and destructor will take care of the InitializeCriticalSection and DeleteCriticalSection calls so you no longer have to worry about them. Speaking of which, I find it extremely useful to have a helper object which enters a CS on construction and then automatically leaves it on destruction. No more critical sections accidentally left locked because a function had an early return hidden in the middle of it...)

Upvotes: 4

OJ.
OJ.

Reputation: 29401

Your requirement doesn't make sense. If your current thread is not the thread which is in the critical section, then the code within the current thread won't be running, it'll be blocked when trying to lock the critical section.

If your thread is actually inside the critical section, then your assertion will always be true. If it's not, your assertion will always be false!

So what I mean is, assuming you're able to track which thread is in the critical section, if you place your assertion inside the critical section code, it'll always be true. If you place it outside, it'll always be false.

Upvotes: -1

casablanca
casablanca

Reputation: 70691

As far as I know, there is no documented way to get this information. If you look at the headers, the CRITICAL_SECTION structure contains a thread handle, but I wouldn't rely on such information because internal structures could change without notice. A better way would be to maintain this information yourself whenever a thread enters/exits the critical section.

Upvotes: 1

Related Questions