MsgWaitForMultipleObjectsEx deadlocks the main STA thread in MFC application - multithreading

What is the best was to do STA thread synchronization?
I have a dialog based MFC application with two STA threads: the main and the second. I created the COM object in the main UI thread.
I call the COM interface from the second thread. In the main thread, to make sure the second thread finishes before the main thread proceeds, I use a loop to wait for the thread. This loop calls MsgWaitForMultipleObjectsEx(timout=500) looply.
I immediately got deadlocked on the wait. Then I realized that the MFC message pump, AfxInternalPumpMessage(), only helps with blocking calls but doesn't help at all with deadlock situations.
Then I added Peek/Translate/DispatchMessage code into the wait loop and then all worked.
Now, it seems that without hand coding the Peek/Translate/DispatchMessage loop, you can't do STA threads synchronization at all? Any wait call will deadlock you. Then what's the best or standard way to synchronize STA threads?
Thanks!

Perhaps you are looking for CoWaitForMultipleHandles?
If the caller resides in a single-thread
apartment, CoWaitForMultipleHandles enters the COM modal loop, and the thread's
message loop will continue to dispatch
messages using the thread's message
filter. If no message filter is registered
for the thread, the default COM
message processing is used.

Not any wait, but any wait that stops running the message loop will indeed deadlock you. The solution is to interleave your wait loop and message loop processing - wait a little, then process all pending messages, repeat.

Related

Waiting std::condition_variable while forking and forked child process is unable to resume it

I am trying to understand forking with multithreading. So what happens in below scenario ?
Application thread has spawned a thread - polling thread
Application thread runs fork
atpthread_fork handler's pre_fork stops the polling thread using a std::condition_variable. It also waits on a different condition variable to resume the polling
atpthread_fork handler's post_fork in child does cv.notify_one for the waiting poll thread and stops the poll thread
atpthread_fork handler's post_fork in parent does cv.notify_one for the waiting poll thread and resumes the poll thread
But what happens is, post_fork in child enters an infinite loop where it keeps on waiting. This also doesn't seem to notified the poll thread cv at all.
Why is this happening ?
I am trying to understand forking with multithreading.
The #1 thing to understand about combining forking with multithreading is don't do it. The combination is highly problematic other than in a handful of special cases.
So what happens in below scenario ?
Application thread has spawned a thread - polling thread
Application thread runs fork
atpthread_fork handler's pre_fork stops the polling thread using a std::condition_variable. It also waits on a different condition
variable to resume the polling
That makes no sense. A condition variable does not have the power to preemptively make any thread stop. And if the polling thread eventually did stop by blocking on the CV, then what role would a different CV have to play in starting it again?
atpthread_fork handler's post_fork in child does cv.notify_one for the waiting poll thread and stops the poll thread
I suppose you meant to say that a post_fork handler registered via pthread_atfork performs a cv.notify_one in the child to resume the poll thread.
Any way around, it is impossible for the child to do anything with the polling thread because it doesn't have one. The child process has only one thread -- a copy of the one that called fork(). This is one of the main reasons why forking and multithreading don't mix.
atpthread_fork handler's post_fork in parent does cv.notify_one for the waiting poll thread and resumes the poll thread
This seems questionable in light of the overall questionable behavior you are attributing to the CVs, but there is nothing inherently wrong with the concept.
But what happens is, post_fork in child enters an infinite loop where
it keeps on waiting.
Something is missing here. Are you doing a timed wait? Is its wait failing? These are the only ways I can think of that the child could be both looping and waiting. There is initially no other thread in the child process to wake the single one that resulted from the fork, so that thread cannot perform a successful return from a wait on any CV, unless spurriously. There is no one to signal it.
This also doesn't seem to notified the poll
thread cv at all.
Do you mean the one in the child that doesn't exist? Or the one in the parent that probably isn't waiting on the CV you think it's waiting on?
Most of the above is moot. There is absolutely no reason to think that your program is exercising one of the special exceptions, so refer to #1: don't combine forking with multithreading. Choose one.

Mechanism of join() in multithreading

I was studying about multi-threading and came across join().
As I understand right, using join() on the thread makes process wait until 'joined' thread terminates. For example, calling t1.join() in main will make main wait until the job in thread t1 is finished and t1 terminates.
I'm just curious that how the function join() make this possible - how does it make current thread 'blocked' inside the function? Does join() force execution of joined thread first so any other thread should wait until that thread terminates? Or, is there some way to communicate between two threads(the thread who called join() and the thread who is joined)?
I will be waiting for the answer. Thanks a lot!
To be able to join you need to be able to wait on some event. Then join looks like this:
function join(t : Thread)
// do this atomically
if already done
return
wait on termination event of t
end
Waiting can be done in one of two ways:
Looping and periodically checking if the event has happened (busy wait)
Letting the system reclaim the resources of the thread and be woken up on a system event, in that case waking the thread is managed by the scheduler of the OS
It's rather language specific.
Once you create a thread, it starts running.
A join operation is when your main process stops and waits for the thread to exit and capture a return code. It will block until your thread completes - that's rather the point, as it allows for a synchronization to occur - everything in your program is at a 'known state'.
Related is the detach operation, which is effectively saying 'I don't care any more'.

How to block other threads to use Synchronize if the main thread is not idle?

I have a TListView in the main Form (Thread) and many other threads that add/delete item from the list using Synchronize method. But the main thread has also a method that modify the list items and I want that method not to be interrupted by other threads that wants to execute code in the main thread. Is this possible ?
Do you have evidence that what you are worried about is happening? You shouldn't, because it can't happen. That is what Synchronize is for. Methods executing in the main thread must complete before the main thread can service the message queue to process work items dispatched via Synchronize from worker threads so you have nothing to worry about.
When a worker thread uses Synchronize it essentially just posts a message to the main thread telling it that it has work for it to do. If the main thread is busy executing another method then the worker thread will simply block until the main thread is finished, subsequently processes the message queue, picks up the work item, executes it, and then posts back to the worker thread that the work is complete (leaving the worker thread free to then continue).
This, of course, assuming that the method in your main thread is not calling Application.ProcessMessages() or CheckSynchronize() (or you are using a tricky component that does this, or something similar, without you knowing it -> see : Delphi 7, Windows 7, event handler, re-entrent code)

Few Questions about Threading, COM+ and STA apartments

I have a windows service which creates 10 threads + the one which creates the tasks list.
Each of these 11 threads enters STA by calling CoInitialize(nil).
Tasks list is created by one thread, other get the item, process it and free ....
a) Can the other thread use the object created by the other thread?
(Thats seems to work, but ..)
b) Can the other thread free the memory allocated by the other thread?
(Thats seems to not work...)
Should I somehow marshal the pointer between threads?
Or should I at least get the item, process it, but let it be freed be the "owner" of the thread which created it?
In my windows services I created the functionality which I can use to start/stop the services(suspand and resume the threads).
However I have a problem with the thread which actually collects the data and does it in the interval.
When the thread loads the items to process, then after it, it enters sleep state for 5 minutes.
How can i terminate such thread safely? How to abort sleep state?
Thanks in advance for your help!
You may have to marshall interfaces across threads. Here you can find a C++ example, and the same articles shows the three techniques you can use (oMarshalInterThreadInterfaceInStream/CoMarshalInterface/Global Interface Table(GIT)). More information about them you can find in MSDN.
To have a thread wait but being able to terminate it before the sleep ends, use WaitForSingleObject() with a proper timeout value and for example a Windows event to wait for. When the functions exit it will tell if it exited because the timeout elapsed or the event was set. To exit the wait function before the timeout is reached simnply set the event. Thereby you can choose if to enter another wait loop or exit.
To marshall an STA object pointer between STA threads use CoMarshallInterThreadInterfaceInStream, and CoGetInterfaceAndReleaseStream.
An STA thread MUST pump messages, as that is how STA threads use COM, using windows messages. I.e. you must call GetMessage/TranslateMessage/DispatchMessage. Probably your framework has a simple message pump function you could use to do this.
To abort your sleep state of 5 minutes, do multiple sleeps for shorter intervals, and check a "shouldquit" flag. Set the shouldquit flag in the Service Main.

Is SetEvent atomic?

Is it safe to have 2 or more threads call the Win32 API's SetEvent on the same event handler not being protected by a critical section?
It's safe, but remember that if one thread Sets it, and another thread Sets it at the same time, you're not going to get two notifications, just one; since the 2nd one changed it from True to...True. If you're worried about this, use Semaphores instead.
Assuming you have multiple threads waiting on the same event, running the same code.
If your code doesnt clear the event until its done processing, you effectively have a CS. Since the event remains signaled until it is cleared(aka not autoreset), having multiple threads signal the does nothing except spin the CPU.
If your code clears it at the begining of processing or the event is autorset, then you would have multiple threads running the same function, which is unsafe if these threads share anything.
there are no restrictions on calling SetEvent from multiple threads.

Resources