Discussion:
SendMessageTimeout - what happens if timeout occurs?
(too old to reply)
Markus Svilans
2006-05-10 18:50:23 UTC
Permalink
Hi,

I've been trying to find more documentation on the SendMessageTimeout()
function without much success. Microsoft's Q106716 document
(http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B106716)
isn't very clear.

I'd like to know what happens when SendMessageTimeout times out. As far
as I can see, two cases are possible:

1. SendMessageTimeout is called. The target HWND never starts
processing the message, and the timeout period elapses.
SendMessageTimeout returns. Does the target HWND eventually process the
message?

2. SendMessageTimeout is called. The target HWND begins processing the
message, but the timeout period elapses before it is done.
SendMessageTimeout returns. In this case, Q106716 seems to indicate
that the target HWND will continue processing the message even though
SendMessageTimeout returned.

Does anyone have any hard facts on what happens in both cases?

Case #1 interests me most, because in my application I want to send a
message to a window, and if it doesn't process the message in time, the
message must not be processed at all. However, before I know exactly
what SendMessageTimeout does, I am reluctant to write too much code
that uses it.

Thanks,
Markus.
Alf P. Steinbach
2006-05-10 19:10:55 UTC
Permalink
Post by Markus Svilans
Hi,
I've been trying to find more documentation on the SendMessageTimeout()
function without much success. Microsoft's Q106716 document
(http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B106716)
isn't very clear.
I'd like to know what happens when SendMessageTimeout times out. As far
1. SendMessageTimeout is called. The target HWND never starts
processing the message, and the timeout period elapses.
SendMessageTimeout returns. Does the target HWND eventually process the
message?
2. SendMessageTimeout is called. The target HWND begins processing the
message, but the timeout period elapses before it is done.
SendMessageTimeout returns. In this case, Q106716 seems to indicate
that the target HWND will continue processing the message even though
SendMessageTimeout returned.
Does anyone have any hard facts on what happens in both cases?
Case #1 interests me most, because in my application I want to send a
message to a window, and if it doesn't process the message in time, the
message must not be processed at all. However, before I know exactly
what SendMessageTimeout does, I am reluctant to write too much code
that uses it.
"Runs to completion" seems to indicate that if the call is issued, it's
never cancelled, and anyway, it would be just too wild if the API did
some setjmp-like thing to roll back a timed out thread, because it can't
know what side effects have already occurred.

I suspect SendMessageTimeout is implemented in terms of
SendMessageCallback, and in that case the calls are definitely issued
(if possible, e.g. not hung destination thread), and not cancelled
whatever happens.

To check on what happened, "If the function fails or times out, the
return value is zero. To get extended error information, call
GetLastError. If GetLastError returns zero, then the function timed
out." With a bit of poetic license, I think "failed" must include the
case where it wasn't possible to call the window procedure, e.g. because
the target thread is hung and doesn't call GetMessage or similar within
the timeout period. But I agree the documentation could be more clear,
and if it feels absolutely too unclear, reinvent the wheel and implement
mySendMessageTimeout in terms of SendMessageCallback.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Markus Svilans
2006-05-10 19:36:11 UTC
Permalink
Post by Alf P. Steinbach
(snip)
"Runs to completion" seems to indicate that if the call is issued, it's
never cancelled, and anyway, it would be just too wild if the API did
some setjmp-like thing to roll back a timed out thread, because it can't
know what side effects have already occurred.
I suspect SendMessageTimeout is implemented in terms of
SendMessageCallback, and in that case the calls are definitely issued
(if possible, e.g. not hung destination thread), and not cancelled
whatever happens.
To check on what happened, "If the function fails or times out, the
return value is zero. To get extended error information, call
GetLastError. If GetLastError returns zero, then the function timed
out." With a bit of poetic license, I think "failed" must include the
case where it wasn't possible to call the window procedure, e.g. because
the target thread is hung and doesn't call GetMessage or similar within
the timeout period. But I agree the documentation could be more clear,
and if it feels absolutely too unclear, reinvent the wheel and implement
mySendMessageTimeout in terms of SendMessageCallback.
Thanks Alf for your insightful response. Too bad we can't look at the
Windows source code to see how these things are implemented...

I'm going to have to experiment with SendMessageTimeout (make it fail
and time out intentionally) to study its behaviour. However it looks
like I will be stuck reinventing at least some parts of the wheel.

Regards,
Markus.
Steve
2006-05-12 11:54:47 UTC
Permalink
PostMessage posts a message to a window and returns immediately leaving
the window to process the message in its own time.

SendMessage sends a message to a window and does not return until the
window finishes processing the message.

SendMessage is particularly useful if sending pointers to structures
where the structures can be "kept in memory" for the duration the
message is processed and the structure can be destroyed after the
message returns. Whereas posting pointers using PostMessage would result
in structures being destroyed before the message gets a chance to be
processed.

SendMessageTimeout is similar to SendMessage. If the timeout is reached
before the message is processed, SendMessage returns and the message is
not processed (the whole point of the timeout period). If the message is
processed during the timeout period, SendMessageTimeout does not return
until processing finishes.
Steve
2006-05-12 12:03:02 UTC
Permalink
Post by Steve
PostMessage posts a message to a window and returns immediately leaving
the window to process the message in its own time.
SendMessage sends a message to a window and does not return until the
window finishes processing the message.
SendMessage is particularly useful if sending pointers to structures
where the structures can be "kept in memory" for the duration the
message is processed and the structure can be destroyed after the
message returns. Whereas posting pointers using PostMessage would result
in structures being destroyed before the message gets a chance to be
processed.
SendMessageTimeout is similar to SendMessage. If the timeout is reached
before the message is processed, SendMessage returns and the message is
not processed (the whole point of the timeout period). If the message is
processed during the timeout period, SendMessageTimeout does not return
until processing finishes.
Sorry. That last sentence should read:

SendMessageTimeout is similar to SendMessage. If the timeout is reached
before the message is processed, SendMessageTimeout returns and the
message is not processed (the whole point of the timeout period). If the
message is processed during the timeout period, SendMessageTimeout does
not return until processing finishes.
Markus Svilans
2006-05-12 14:44:14 UTC
Permalink
This is how I suspected SendMessageTimeout works. That's exactly what I
want to do, process structures that must be "kept in memory" while the
message is processed.

Based on what you say then, in Case #2 from my original post,
SendMessageTimeout will only return if (a) the time out period expires
or (b) the message is processed. If the timeout period expires during
message processing, then SendMessageTimeout will only return after the
message processing completes. This would be the expected behaviour.

However I still can't find any clear official documentation that
confirms this. Do you know of any?

I suppose I'm just being lazy, because I should probably write some
experimental code to check how SendMessageTimeout() works, but that's
icky. :)

Thanks.
Steve
2006-05-12 15:36:47 UTC
Permalink
Post by Markus Svilans
This is how I suspected SendMessageTimeout works. That's exactly what I
want to do, process structures that must be "kept in memory" while the
message is processed.
Based on what you say then, in Case #2 from my original post,
SendMessageTimeout will only return if (a) the time out period expires
or (b) the message is processed. If the timeout period expires during
message processing, then SendMessageTimeout will only return after the
message processing completes. This would be the expected behaviour.
However I still can't find any clear official documentation that
confirms this. Do you know of any?
I suppose I'm just being lazy, because I should probably write some
experimental code to check how SendMessageTimeout() works, but that's
icky. :)
Thanks.
The flags parameter seems interesting:

fuFlags:
[in] Specifies how to send the message. This parameter can be one or
more of the following values.

SMTO_ABORTIFHUNG
Returns without waiting for the time-out period to elapse if the
receiving thread appears to not respond or "hangs."
SMTO_BLOCK
Prevents the calling thread from processing any other requests until the
function returns.
SMTO_NORMAL
The calling thread is not prevented from processing other requests while
waiting for the function to return.
SMTO_NOTIMEOUTIFNOTHUNG
Microsoft® Windows® 2000/Windows XP: Does not return when the time-out
period elapses if the receiving thread stops responding.

Remarks

The function calls the window procedure for the specified window and, if
the specified window belongs to a different thread, does not return
until the window procedure has processed the message or the specified
time-out period has elapsed. If the window receiving the message belongs
to the same queue as the current thread, the window procedure is called
directly—the time-out value is ignored.

This function considers a thread is not responding or is "hung" if it
has not called GetMessage or a similar function within five seconds.

The system only does marshalling for system messages (those in the range
0 to WM_USER). To send other messages (those above WM_USER) to another
process, you must do custom marshalling.

This is the official MSDN documentation.
Grzegorz Wróbel
2006-05-13 10:46:03 UTC
Permalink
Post by Steve
PostMessage posts a message to a window and returns immediately leaving
the window to process the message in its own time.
Unless message queue of the window is full in which case targeted window won't get posted message.
Post by Steve
SendMessage sends a message to a window and does not return until the
window finishes processing the message.
SendMessageTimeout is similar to SendMessage. If the timeout is reached
before the message is processed, SendMessage returns and the message is
not processed (the whole point of the timeout period).
I would say the purpose of SendMessageTimeout() is to avoid deadlocks in case application would be sending message to the application that is hung or for other reason won't process the message. The behaviour you described (message is not processed in that case) is probably true, unfortunatelly documentation does not say this.
Post by Steve
If the message is
processed during the timeout period, SendMessageTimeout does not return
until processing finishes.
--
677265676F727940346E6575726F6E732E636F6D
Grzegorz Wróbel
2006-05-13 10:47:17 UTC
Permalink
Post by Steve
PostMessage posts a message to a window and returns immediately leaving
the window to process the message in its own time.
Unless message queue of the window is full in which case targeted window won't get posted message.
Post by Steve
SendMessage sends a message to a window and does not return until the
window finishes processing the message.
SendMessageTimeout is similar to SendMessage. If the timeout is reached
before the message is processed, SendMessage returns and the message is
not processed (the whole point of the timeout period).
I would say the purpose of SendMessageTimeout() is to avoid deadlocks in case application would be sending message to the application that is hung or for other reason won't process the message. The behaviour you described (message is not processed in that case) is probably true, unfortunatelly documentation does not say this.
Post by Steve
If the message is
processed during the timeout period, SendMessageTimeout does not return
until processing finishes.
--
677265676F727940346E6575726F6E732E636F6D
Loading...