I have a thread which creates a hidden window for the purpose of receiving WinAPI messages based on power state. I need to get the HWND
of the created window from the thread so that I can throw a WM_QUIT
message to close the window and end the thread gracefully:
Main:
HWND hiddenWindowHandle = NULL;
HANDLE PowerWindowThreadHandle = (HANDLE)_beginthreadex(0, 0, &windowsPowerThread, (void*)&hiddenWindowHandle, 0, 0);
Thread:
unsigned int __stdcall windowsPowerThread(void* data)
{
HWND hiddenWindowHandle = createHiddenWindow();
HWND hwHandle = *(HWND*)data;
hwHandle = hiddenWindowHandle;
...
The problem is that the hiddenWindowHandle
is not being updated with the generated HWND
.
I have verified in the thread that it's being created, and I've verified that I'm not trying to access the handle before the thread creates it.
What am I missing here?
Your code lacks the necessary synchronization. What you have here is a data race. Thus, what you get is strictly undefined behavior. What will most likely happen is that the compiler simply does not re-fetch the value of
hiddenWindowHandle
from memory in every iteration of the loop, since it can simply assume that the value does not change. One possible solution would be to makehiddenWindowHandle
anstd::atomic
and have the main thread perform a busy wait until the value changes fromNULL
. Alternatively, you could put all access to the shared variable into a critical section locked by a mutex, or use a condition variable to wait for the value to be available.Edit based on comments:
So if I understand your code correctly, the thread that creates the window receives a pointer to the result variable in the form of a
void*
and then tries to communicate the result like so:There's two problems here. First of all,
data
doesn't point to anHWND
, it points to anstd::atomic<HWND>
now, so you already have undefined behavior there. The main problem, and probably the explanation why your original code didn't just happen to work anyways, despite the data race, is that you create a new localHWND
calledhwHandle
. This local variable is initialized with the value of whateverdata
points to. You then assign your result to that local variable, but never to the actual result variable.What you want to do is more something along the lines of
You may also want to consider using
std::thread
instead of the raw CRT functions.