The internal mechanism of GetMessage() in Win32 API? - windows

In the Message Loop of a windows application,the GetMessage() function will suspend the application thread when there is no message in the message queue, but how it manages to wake itself up when a message was enqueued into the message queue? How can a sleeping thread wake itself up?
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}

The thread doesn't wake itself up. The thread that sends it the message wakes it up. Part of the process of sending a message includes waking the recipient of the message.

They wait in the same manner as how a typical asynchronous wait thread waits (using WaitForSingleObject). Internally (in the kernel level), they all wait using a kernel API function called KeWaitForSingleObject

Related

Why are threads created with message queues?

This is windows specific question.
According to microsoft docs,
The system maintains a single system message queue and one thread-specific message queue for each GUI thread. To avoid the overhead of creating a message queue for non–GUI threads, all threads are created initially without a message queue. The system creates a thread-specific message queue only when the thread makes its first call to one of the specific user functions; no GUI function calls result in the creation of a message queue.
So far I believed on that all threads are created initially without a message queue. Today, I tested this with PostThreadMessageW because it is stated that
The function fails if the specified thread does not have a message queue.
However, PostThreadMessageW always returns 1 (TRUE) for all threads right after creation.
DWORD dwThreadID = GetCurrentThreadId();
BOOL bResult = PostThreadMessageW(dwThreadID, WM_QUIT, 123, 456);
Why is this happening?

The JMS receiver thread and the onMessage() callback

I have looked at similar threads but did not get a satisfactory reply.
In the JMS receiver thread, I see a while loop coded as follows:
while(true)
{
Thread.sleep(1000);
}
The above thread also has a registered listener attached to it, which implements the messageListener interface and thus provides for the the callback onMessage() event.
When the onMessage() event gets triggered on the listener, what happens to the receiver thread?
Does its state become false? Does it get interrupted (and throws an interrupted exception)?
What exactly happens at the while loop stated above?
The code above is simply saying 'wait forever' - it most likely is a hastily designed way of NOT ending this thread before someone hits Ctrl-C. The code of while(true) will always be true, so it just blocks here until this thread is interrupted. There is no magic inside this thread !
However in your second (invisible) 'message dispatcher thread' that has been automatically created in Connection.start() messages are received and dispatched to your onMessage() method. Until you call Connection.stop() or your exit your program.

Is SendMessage or SendMessageTimout thread safe?

I have a very basic question : is SendMessage or SendMessageTimout thread safe ?
SendMessage :
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644950(v=vs.85).aspx
SendMessageTimout
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644952(v=vs.85).aspx
Related:
Sending message from working non-gui thread to the main window
SendMessage and SendMessageTimeout are blocking functions: They pause the sender until the receiver has processed the message and returned. So there is no concurrent access to anything, hence the operation is thread-safe.

Is Application.DoEvents sending messages to a separate thread?

I've been trying to understand event loops (not going so well) in general and I've read that the windows messaging loop is single threaded. If it is, how can Application.DoEvents work? Doesn't an event loop process one message at a time and blocks while each message/event is being processed? Wouldn't the message event loop need to exist on a different thread from the one that is processing the message for Application.DoEvents to be possible? If there are separate threads, which one is it that we're calling the "main" thread? I'm sure I'm missing something very simple, I just don't know what it is.
I spend the better part of the day figuring this out (if anything I say is wrong, please comment and let me know so I can correct it). I actually had to build an old Win32 application and create the message loop myself (I'm a pretty persistent SOB). So there is a function called WinMain that starts up the message loop which looks like this:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
The thing about GetMessage() is that it blocks until a message is available in the message queue. If you run a Windowed application and just sit there and look at the window (don't cause any actions that would post a message to the queue), the main thread (the thread the window was created on) is paused on GetMessage(). Now when a message does get posted, we enter the while loop (that is if the message is not quit which is 0). DispatchMessage() is the interesting function here. This function will eventually lead to (in .NET) events being raised by controls and execution of EventHandlers. What puzzled me is if the call stack is GetMessage()/DispatchMessage()/.../EventHandler, how is it possible for Application.DoEvents() to process messages? Well it's pretty simple. DoEvents in Win32 would look like this:
void DoEvents()
{
MSG msg;
HACCEL hAccelTable;
hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDC_TESTWIN32));
// Main message loop:
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE) != 0)
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
So DoEvents() actually starts up another loop to process events while inside the initial message loop's DispatchMessage()! The key difference is that instead of using GetMessage() which blocks until there is a message in the queue, we use PeekMessage() which returns 0 and exists the loop when there are no longer any messages in the queue.
So what if we click a button twice and in that button's EventHandler we have a DoEvents() call? The initial event loop will process the first click and fire the event. While the EventHandler is executing, at the DoEvents() call, the event will be fired a second time and the EventHandler will be entered again (sort of like a recursive call). That's scary!
So in the end, everything is happening in a single thread and DoEvents() actually blocks until all messages are processed then returns. Now I'm going to go to sleep for a couple days.

PostThreadMessage returns ERROR_INVALID_THREAD_ID

I have a multi-threaded simulation running on Windows Vista. When I use PostThreadMessage to send messages between threads, I am getting ERROR_INVALID_THREAD_ID, even though I am quite certain (from stepping through the debugger) that the thread id is valid, and the thread has a message queue, since I call PeekMessage from every thread after I create them, as specified in MSDN. It's likely the target thread is suspended, but that should not be a problem, as far as I can tell.
Any clues on what to try? I am simulating an RTOS based application, so I'm hoping not to have to put in too much Windows specific code.
EDIT -
Another clue - if I remove all the semaphore blocking, the messages work fine (although there are some known race conditions). But message queues should not be affected by thread blocking, right?
Edit 2
The code also has the following retry mechanism, as suggested by MSDN. But it still does not work - the retry always fails. hmmm.....
BOOL bResult = false;
int retry = 0;
DWORD dwError = 0;
do
{
bResult = PostThreadMessage(pTaskHandle->dwThreadID,0,0,(LPARAM)pMessage);
if (!bResult)
{
dwError = GetLastError();
retry++; // should only happen once, if the dest thread has no msg queue
// the retry establishes the queue
Sleep(500);
}
} while (!bResult && retry<3); // MSDN says try this a few times to start msg queue
You mention you call PeekMessage after creating the threads but do these threads have full, active message processing loops that are dispatching the messages? msdn says:
Call PostThreadMessage. If it fails, call the Sleep function and call PostThreadMessage again. Repeat until PostThreadMessage succeeds.
which sounds a little goofy if the only requirement is that the thread called PeekMessage once.
Also be aware that messages posted via. PostThreadMessage don't get dispatched in DispatchMessage. this seems obvious since there's no window for the message to go to, but I've seen people do it, especially when using MsgWaitForMultipleObjects and such to wait on a handle. in this case it seems unlikely you'd get ERROR_INVALID_THREAD_ID... more likely you'd just miss the message.

Resources