Re: CWinThread and Memory Leaks.

From: Doug Harrison [MVP] (dsh_at_mvps.org)
Date: 01/14/05


Date: Thu, 13 Jan 2005 20:15:44 -0600

jim_OLP wrote:

>I've tried to do a similar progress dialog thing using CWinThread. What
>I find is that if the main thread blocks inside a message handler, the
>progress UI thread can't dispatch any messages. It looks to me like
>multiple CWinThreads are interlocked/synchronized such that only one
>can be dispatching a message at any given time. In other words,
>CWinThread is useless. Am I missing something? Was this true before VC
>7.0?

CWinThread does not do that. It sounds like you have an interthread
SendMessage situation, which is a Windows issue. It can arise not only by
calling SendMessage directly but by calling most any function that
manipulates a window and isn't spelled "PostMessage", as things like
SetWindowText use SendMessage under the hood. Here's an excerpt from one of
my recent messages here which expands on this:

SendMessage is a synchronous call. When the target is a window created by
the calling thread, it amounts to an ordinary function call. When the target
is a window created by a different thread, the calling thread blocks until
the target thread is in a receptive state, i.e. it makes a call to one of a
handful of functions that are considered safe points to dispatch pending
interthread sent messages, e.g. GetMessage, PeekMessage, etc. When the
system detects the target thread is in such a state, it switches to that
thread, which goes on to handle the message. In the meantime, the calling
thread sits there blocked until the target finishes the message, either by
returning from its message handler or by calling ReplyMessage.

That said, it's quite possible to design a system that works properly with
interthread SendMessage. The major requirement is that the target thread
enter the receptive state on a regular, timely basis, because outside this
state, it cannot dispatch interthread sent messages, and callers will sit
there unable to continue until the target enters the receptive state. In
well-designed programs, GUI threads pretty much meet this requirement by
definition, because to keep the GUI responsive is to process messages with
low latency, and this allows interthread SendMessage to work.

What about the deadlock potential? It's always an issue when using
synchronization, and interthread SendMessage is a form of synchronization.
There is a great deal of confusion concerning the likelihood of deadlock
when the target window merely wants to send a message to a window in the
calling thread, as happens in many parent/child window scenarios. Raymond
Chen addressed this in his blog:

When can a thread receive window messages?
http://weblogs.asp.net/oldnewthing/archive/2004/06/08/150929.aspx
<q>
If one thread T1 send a message to a window that belongs to another thread
T2, the sending thread T1 is put to sleep until the receiving thread replies
to the message. But if somebody else sends a message to thread T1, thread T1
is woken to process the message, then is returned to sleep.
...
Another case is that thread T1 sends a message to thread T2, and thread T2
needs to ask thread T1 for help before it can finish the operation. This
isn't as strange as it sounds. You do something similar all the time without
realizing it when you respond to a WM_NOTIFY message by sending messages
back to the control that sent the notification. (For example, you may
respond to a LVN_ITEMACTIVATE by sending back a LVM_GETITEM to get
information about the item that was activated.)
</q>

So, it appears this common concern is not actually a problem at all, because
the receptive state includes being blocked in interthread SendMessage.

The main question you need to ask yourself when thinking about using
interthread SendMessage is, "Do I really need this call to be synchronous?"
If the answer is "yes," then you simply have to make it safe, and the
preceding discussion should guide you in this. If the answer is "no," then
just use PostMessage. However, if the answer is, "I don't know, but to be
safe, I think I can replace it with some send/ack scheme using PostMessage,"
you need to ensure that the replacement method really is safe, and what your
app can do between posting the message and receiving the acknowledgement
doesn't mess you up. In particular, if you return to your main message loop,
which is typical, you put your whole program in play, which can invalidate
your assumptions about what can happen between the post and the ack. IOW,
the program may be in an unanticipated state when the ack is received, and
more than anything, this points out why, "I don't know, but to be safe..."
is an inadequate basis on which to proceed. Anyway, these are the sorts of
things you need to think about.

-- 
Doug Harrison
Microsoft MVP - Visual C++


Relevant Pages

  • Re: boot problem
    ... in the center window), ... Assuming you have been able to run Target Analyzer, ... particularly 'Step 3 Create a New Configuration': ... > the installed the compact flash into the target system (it has a bootable ...
    (microsoft.public.windowsxp.embedded)
  • Re: how do i setup hyperlinks in publisher 2003 to open in a new w
    ... Q. How do I make my hyperlink open the URL in a new browser window? ... Publisher does not have any support for this. ... to code a target when linking within Publisher. ... > No you don't want to use javascript, you need to use a html link with the ...
    (microsoft.public.publisher.webdesign)
  • Re: keyboard event
    ... >> edit control residing on the parent window). ... you can walk it to get to the hWnd of the target window. ... >ok thanks Bryan ...
    (microsoft.public.vb.winapi)
  • Re: Encrypt String or different approach
    ... > Don't use a GET (using a querystring), but rather a POST to the target ... >> those processes is to allow them to download files in their FTP Root ... >> then provides a link that would spawn a new window which would initiate ...
    (microsoft.public.dotnet.framework.aspnet.security)
  • Re: Encrypt String or different approach
    ... > Don't use a GET (using a querystring), but rather a POST to the target ... >> those processes is to allow them to download files in their FTP Root ... >> then provides a link that would spawn a new window which would initiate ...
    (microsoft.public.dotnet.framework.aspnet)