Board index » cppbuilder » TThread Synchronize hangs

TThread Synchronize hangs


2007-07-18 06:32:45 AM
cppbuilder56
BCB6 patched.
I have a COM server. That server contains a background thread. The
background thread calls Syncronize(someMethod); However - "someMethod"
never gets called. The client application is a GUI. It created the COM
object, invokes a function which in turns starts the background thread.
This all seems to work OK. I see the thread later wake up and call the
Synchronize(someMethod) - where it hangs.
I also note that the GUI is responsive (and so is processing messages).
I also note that at the moment the GUI is closed, "someMthod" is called.
Any ideas?
 
 

Re:TThread Synchronize hangs

"bilbo" < XXXX@XXXXX.COM >wrote in message
Quote
I have a COM server.
An in-proc server or an out-of-proc server?
Quote
That server contains a background thread. The background
thread calls Syncronize(someMethod); However - "someMethod"
never gets called.
Then your app's main thread is not pumping the message queue for new VCL
messages.
Quote
The client application is a GUI.
Is it written in BCB 6 as well?
Quote
I also note that the GUI is responsive (and so is processing messages).
That does not necessarily mean that the GUI thread is processing the
messages that Synchronize() needs.
Gambit
 

Re:TThread Synchronize hangs

"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote
Quote
>I have a COM server.

An in-proc server or an out-of-proc server?
In-Proc.
Quote
>That server contains a background thread. The background
>thread calls Syncronize(someMethod); However - "someMethod"
>never gets called.

Then your app's main thread is not pumping the message queue for new VCL
messages.
Hmmm - odd, I wonder why?
Quote
>The client application is a GUI.

Is it written in BCB 6 as well?
Yes it is.
 

{smallsort}

Re:TThread Synchronize hangs

"bilbo" < XXXX@XXXXX.COM >wrote in message
Quote
In-Proc.
Synchronize() puts the specified method pointer into a global list, notifies
the main thread that it needs to process the list, and then waits for the
method to finish its work. However, a DLL does not have access to the main
application's list, and vice versa. Your code doesn't work because the DLL
is maintaining its own local list that the main app can't execute. So the
thread's method is stored in the DLL's list, which the app never calls, and
the thread becomes deadlocked.
The only reason your code wakes up on shutdown is because TThread's
destructor is checking the DLL's list and executing any stored methods while
waiting for the thread to exit. The destructor waits until the thread's
method finally executes, then the thread sees the Terminated property has
been set so it exits, allowing the destructor to finish its cleanup.
As such, you can't use Synchronize() in a DLL at all, because there is no
way to make the list be processed correctly. You will have to re-think your
DLL's design to use a different kind of synchronization.
Gambit
 

Re:TThread Synchronize hangs

Thanks Remy,
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote
[...]
Quote
As such, you can't use Synchronize() in a DLL at all, because there is no
way to make the list be processed correctly. You will have to re-think
your
DLL's design to use a different kind of synchronization.
Let me explain what I need to accomplish and maybe you can suggest a better
way to do it.
1) The in-proc COM server is distributed to arbitrary third party
developers - so it has to use all COM standards.
2) The server is called once (say Foo()) from inside these client
applications and Foo() must start up a background thread (say ThreadX)
inside the server to perform some regular monitoring. It does this moniting
using a waitable timer and WaitForSingleObject(). The monitoring in ThreadX
is done repeatedly until the app exits. Foo returns and the client continues
while ThreadX does its work.
3) When ThreadX's timer fires and it detects a certain condition, it must
fire an IDispatch event (say EventX) to the client app (who of course had
previously connected a sink), passing some parameters, informing the client
that this certain event has ocurred. The client can respond as they like and
the EventX eventually retuns to the COM server. When EventX returns,
ThreadX goes back into the wait.
The waiting logic and event logic all seems to be working fine. I would
simply throw away Synchronize() and fire the event back at the client, but
thats not right. When I try that, I get *BizzArE* results in the client app
which I believe to be because it is not Synchronize()d. An example of this
bizzarre behaviour is: in the event handler in the client I just do a
MessageDlg(), but some times the dialog is so large it fills the entire
screen, other times it contains no caption or text, other times the button
is entirely the wrong size, etc.
Ideas?
 

Re:TThread Synchronize hangs

"bilbo" < XXXX@XXXXX.COM >wrote in message
Quote
When ThreadX's timer fires and it detects a certain condition,
it must fire an IDispatch event (say EventX) to the client app
(who of course had previously connected a sink), passing some
parameters, informing the client that this certain event has ocurred.
The client can respond as they like and the EventX eventually
retuns to the COM server. When EventX returns, ThreadX
goes back into the wait.
Then I suggest you make the COM object be free-threaded, and let it call the
sink directly without any synchronization performed by the thread. Have the
application be responsible for its own synchronization as needed. Don't do
it inside the DLL itself.
Using threads inside of a COM object, especially when a sink is involved, is
a very tricky and very delicate thing to implement properly in general,
regardless of whether you are using the VCL or not.
Quote
I would simply throw away Synchronize() and fire the
event back at the client, but thats not right.
It can be, if implemented properly in the COM object's code, and documented
correctly so the users know that their callbacks need to be thread-safe.
I've made multi-threaded COM objects before, so I know this approach can
work in general, though I've always implemented them as out-of-proc servers
instead of in-proc servers. I never have need to use threads in an in-proc
server.
Quote
in the event handler in the client I just do a MessageDlg(),
but some times the dialog is so large it fills the entire screen,
other times it contains no caption or text, other times the
button is entirely the wrong size, etc.
MessageDlg() displays a VCL TForm, so it is not thread-safe. Use the Win32
API MessageBox() function instead.
Gambit