https://bugs.winehq.org/show_bug.cgi?id=3930
--- Comment #88 from zebra2745@vibzi.net ---
That doesn't work, because GetCurrentThread() only returns a pseudo handle, "a special constant that is interpreted as the current thread handle" (MSDN). I think we have to compare the globally unique thread IDs to be sure:
https://www.codeproject.com/Tips/5350589/The-Current-Thread-Handle says:
What to do when you want to use the current thread handle This tip shows a side effect of GetCurrentThread and explains what to do when you need to avoid that.
Introduction When you need to get a handle to the current thread, you can use GetCurrentThread which gives you a pseudo handle which you don't need to close because it is not a real reference counted handle. This is mentioned clearly in the documentation. However, I recently bumped my head against this. I wanted to share it so that others can avoid having to chase this down.
My Headbump Consider the following example:
------------------------------ snip ------------------------------
DWORD worker(void* ctx) { std::cout << "Thread id: " << GetThreadId((HANDLE)ctx) << std::endl; return 0; }
int main() { HANDLE hMainThread = GetCurrentThread(); std::cout << "Thread id: " << GetThreadId(hMainThread) << std::endl;
HANDLE hThread = CreateThread(NULL, 0, worker, hMainThread, 0, NULL); WaitForSingleObject(hThread, INFINITE); }
------------------------------ snip ------------------------------
This is what happens: Thread id: 44068 Thread id: 36376
Without thinking, I had assumed that the pseudo handle was just a weak copy of the actual handle (a non reference counted copy of the current handle), and I could reference it in a worker thread. Instead, it is a special constant that literally means 'when this handle value is supplied, use the current thread'. And if you pass that special value to another thread, then that value will translate to the thread handle of 'that' thread.
If you read the documentation, then this is exactly what it says. Only I didn't stop to think about what that actually meant.
Getting the Real Thread Handle If you want to get a real handle that you can pass to another thread, do this:
------------------------------ snip ------------------------------
HANDLE hMainThread = NULL; if (!DuplicateHandle( GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hMainThread, 0, FALSE, DUPLICATE_SAME_ACCESS)) { cout << "Error " << GetLastError() << " cannot duplicate main handle." << endl; return GetLastError(); }
------------------------------ snip ------------------------------
Of course, when you do this, you get a HANDLE value that you do need to close when you no longer need it.