PostThreadMessage: Create a message queue - multithreading

I have an issue concerning a Thread lacking a message queue at the begin of its life cycle. MSDN explains
The thread to which the message is posted must have created a message queue, or else the call to PostThreadMessage fails. Use one of the following methods to handle this situation:
(1) Call PostThreadMessage. If it fails, call the Sleep function and call PostThreadMessage again. Repeat until PostThreadMessage succeeds.
(2) Create an event object, then create the thread. Use the WaitForSingleObject function to wait for the event to be set to the signaled state before calling PostThreadMessage. In the thread to which the message will be posted, call PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE) to force the system to create the message queue. Set the event, to indicate that the thread is ready to receive posted messages.
Method (1) solves my issue, the second call to PostThreadMethod() always succeeds in my application.
However, I would like to comprehend the second method and simply don't understand "event object" (certainly not a normal Delphi event?) "to the signalled state" and "set the event to indicate".
QUESTION: Can someone please be so kind as to translate paragraph (2) into a short Delphi code example?

These event objects are synchronization objects, described in MSDN here: Event Objects.
At the bottom of that topic is a link to Using Event Objects which gives example code showing how to create events, set them, wait for them, etc.
In short you use the following functions:
CreateEvent to create the event objects.
CloseHandle to destroy it.
SetEvent and ResetEvent to set and reset the event object.
WaitForSingleObject to wait for it to be signaled.
You can use the TEvent class from the System.SyncObjs unit to wrap all of these low-level API calls. Then the process would become like so:
Create a TEvent object, Event say, in the reset state.
Create your worker thread, passing in Event.
Call Event.WaitFor in the manager thread to wait for the worker thread to signal that its message queue exists.
When the worker thread starts executing (i.e. at the start of its Execute method), have it create its message queue, and then set the event by calling Event.SetEvent.

Related

How to make WM_TIMER msg be called in ordered sequence in WinApi?

I'm doing winapi programming and i usually have a problems related to WM_TIMER msg: for example, when i put function that activates when WM_TIMER msg is called, like Update() function for example, this function is still called even though i killed timer. What's the main problem right now is that when i believe that i deleted the class that contain Update() function, this class still calls Update() function even though i killed timer and this class first, and because of this, i get memory error because this Update() function deals with attributes that are already deleted in previous delete function. Is there any solution to make WM_TIMER be called after certain task is done?
The WM_TIMER message is actually a flag -- when some timer expires, the flag is set to generate a single WM_TIMER event if the message queue is empty and GetMessage is called.
This avoids clogging up the system with many WM_TIMER messages and collapses multiple expired timers into one, but has the disadvantage of delivering the WM_TIMER message after all other messages (WM_PAINT is treated similarly).
So what you are seeing is that the timer you have killed has already elapsed and the flag is set, but the message will not be delivered until your program is otherwise idle.
You want to keep a flag to memorize whether you are actually waiting for a timer event.
In an application with multiple timers in parallel you'd keep a list of active timers, and use the Windows timer mechanism to schedule the next timer to elapse, and in the handler, invoke all sub-handlers whose deadlines are past.

Is safe and good design AllocateHWND to respond more than one thread?

It's known that, in cases when one needs comunicate between UI thread and working thread, an hidden window must be created because of thread safety(handle reconstruction).
For exemplify:
Form1 has N dynamicaly created TProgressBar instances with the same name of a background running .
Is always garanteed that WM_REFRESH will only be called inside Task Thread.
Form1 has H : THandle property that allocates the following procedure:
procedure RefreshStat(var Message: TMessage); message WM_REFRESH;
Inside RefreshStat, in cases when there is only 1 background thread I could easily use L and W parameter to map Task Id and position.
I don't know if the title says what I want to know, but let's imagine if we have an application that has multiple background tasks running.
In my case I use TProgressBar to report progress the done.
Does AllocateHwnd garantee that all messages arrives with no race condition the hidden window?
What happens if two or more tasks post the message at the same time?
If this needs to be controled manually, I wonder if there is something else to do besides creating another message loop system in the custom message.
I hope the question is clear enough.
The message queue associated with a thread is a threadsafe queue. Both synchronous and asynchronous messages from multiple other thread are delivered safely no harmful date races. There is no need for any external synchronization when calling the Windows message API functions like SendMessage and PostMessage.
If two threads post or send messages to the same window at the same time, then there is no guarantee as to which message will be processed first. This is what is known as a benign race condition. If you want one message to be processed before the other then you must impose an ordering.

Are the signal-slot execution in Qt parallelized?

I have a basic Qt question on the way it handles Signals and Slots. I am very new to the framework, so pardon me if it sounds stupid. I was wondering if I have certain signals connected to certain slots.
signal1() ---> slot1(){ cout <<"a"; }
signal2() ---> slot2(){ cout <<"b"; }
signal3() ---> slot3(){ cout <<"c"; }
And in my code I call
emit signal1();
emit signal2();
emit signal3();
Does Qt guarantee to print out "abc" to the screen, in other words process the slots sequentially? Or will it spawn a separate thread to execute each slot?
Thanks!
By default:
1) If the signal is emitted in the thread which the receiving object has affinity then the slots connected to this signal are executed immediately, just like a normal function calls. Execution of the code following the emit statement will occur once all slots have returned.
2) Otherwise, the slot is invoked when control returns to the event loop of the receiver's thread. The code following the emit keyword will continue immediately, and the slots will be executed later in the receiver's thread.
More info about connection types here: http://qt-project.org/doc/qt-4.8/threads-qobject.html#signals-and-slots-across-threads
Just to add to Kotlomoy's correct answer :)
You can also control the type of connection from the default by supplying the optional parameter ConnectionType:
connect(obj, signal, obj, slot, connectionType)
Where your main options are:
Qt::QueuedConnection: This will only run when control returns to the event loop of the thread. I.e. will be added to the queue. specify this if you don't want your slot to be processed immediately which can be very useful.
Qt::DirectConnection: Alternatively you can specify direct connection (even between threads if you want), but generally you do not need or want to use this option since it is default when a signal is emitted to a slot within the same thread.
If you use QueuedConnection you grantee "abc" to be printed to the screen in that order.
Its worth noting if a directConnect event occurs while you are processing a previous slot (lets say some other external event triggers a signal like an IpSocket input) then you will get "interrupted". This won't happen in your simple example.

Is there a pattern to cancel a block on another dispatch queue?

This could be a much more generic question abut how to best cancel blocking jobs on other threads, but I'm interested in a solution in the context of Grand Central Dispatch. I have the need to call a function which basically blocks until it gets data from the network; it could potentially be blocked forever. I have it set up now so that this blocked call happens on a private dispatch queue, and when i do get data, i put a block back on the main queue. Th e problem is that once I dispatch my private-queue-block and blocking call, I can never really cancel that. Imagine this ability was tied to a user setting toggle. If they toggled off, I would want this blocking job and execution block to essentially just end. Is there a good solution to this type of problem?
Thanks
- (void)_beginListeningForNetworkJunk
{
dispatch_async(my_private_queue, ^{
// blocks until it gets data
id data = [NetworkListener waitForData];
dispatch_async(dispatch_get_main_queue(), ^{
[self _handleNetworkData:data];
});
});
}
- (void)_endListeningForNetworkJunk
{
// How do I kill that job that is blocked on my private queue?
}
You can't. The problem is in NetworkListener in its blocking-and-uninterruptible interface.
Normally, you'd code the block to service the network connection asynchronously and also monitor some other signalling mechanism, such as a custom run loop source (or NSPort or pipe file descriptor or …). When the network connection had activity, that would be serviced. When the signalling mechanism fired, you would shut down the network connection and exit the block.
In that way, the block could be cancellable with its cooperation.
Since your block is stuck in -waitForData, it can't cooperate. There's no mechanism for canceling blocks without their cooperation. The same is true of NSOperation and NSThread. The reason is that it's basically infeasible to terminate another thread's activity without its cooperation.
You need a different design for your networking code.
In principle, you can't cancel anything running on any other thread. You can only politely ask the task that is running on another thread to cancel. I usually create objects representing tasks so that "cancel" can be called on these objects.
In your situation: The waitForData cannot be cancelled (unless NetworkListener has some API to do it; in that case waitForData would need some mechanism to distinguish between data arriving and cancellation).
In _endListenForNetworkJunk, you can set a BOOL value "cancelled" to indicate the call is cancelled. Then in the code that runs on the main queue, check whether that "cancelled" value is still cleared. That way, if you call _endListenForNetworkJunk from the main thread, you're sure that _handleNetworkData will not be called. If you call _endListenForNetworkJunk from another thread, the main thread could just have started the call to _handleNetworkData.
If you checked "cancelled" just before dispatching to the main queue, that block could already be dispatched but not executing just before you call _endListenForNetworkJunk on the main thread.

How do I add an event handler for when a thread finishes in MFC?

At the moment, I am using WaitForSingleObject to wait for a sub-task thread to complete. Unfortunately, this causes my GUI to lock up. What I would like to do instead, is set a handler (in the GUI thread) that will be called after the sub-task thread is complete. Is there another function for this?
What you can do is to let the last thing that your thread does be posting a custom message to your window. Then handle that as a regular message using MFC's message map. If you cannot change the thread code, you can create a new thread that waits for your thread and then sends the message.
As you already noticed, it is not a good idea to lock up the GUI thread...
Edit: Posting the message is done using the PostMessage function as pointed out by Hans in the comments.
Could also have a look at MsgWaitForMultipleObjects (or MsgWaitForMultipleObjectsEx).
These allow a thread to wait for event handles and service windows messages (examine the return value to see what causes the call to return). Examples of usage should be available via a goodle search.
http://msdn.microsoft.com/en-us/library/ms684245(VS.85).aspx

Resources