Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PostThreadMessage messages lost

755 views
Skip to first unread message

Randy

unread,
Dec 10, 2002, 10:50:13 AM12/10/02
to
I appear to be losing messages posted using PostThreadMessage. I have a
worker thread created that fetches messages using GetMessage. I also know
that the message queue is created since I waited for it to be created using
a synchronization event.

If I only post one message to the thread it is fine. But if I post two
messages right after one another the second one is lost and
PostThreadMessage doesn't return an error.

Example.

PostThreadMessage(somemessage); //works

Example2.

PostThreadMessage(somemessage);
PostThreadMessage(somemessage2);

The second message in example2 seems to disappear and PostThreadMessage
doesn't fail. However this causes it to work.

Example3.
Sleep(0);
PostThreadMessage(somemessage);
PostThreadMessage(somemessage2);

I am completely baffled by this and hope I don't have to call Sleep
everytime I want to post messages to my thread. By the way the thread I am
posting to has NO WINDOWS, so I know the messages aren't being intercepted.

Please help :)


no...@none.com

unread,
Dec 10, 2002, 11:11:13 AM12/10/02
to
Check the remarks in the Platform SDK documentation for this function. It
basically says:

while ( !PostThreadMessage( ... ) )
{
Sleep(10);
}

Or use event objects.


"Randy" <z...@somewhere.com> wrote in message
news:u1wYZOGoCHA.948@TK2MSFTNGP10...

Fred Fischer

unread,
Dec 10, 2002, 11:47:32 AM12/10/02
to
I'm using PostThreadMessage() and it works fine for me once the message
queue has been created.

The SDK documentation I have mentions using Sleep() or
WaitForSingleObject(), but only to handle the case where the message queue
has not yet been created. Randy's comments imply that the message queue
*does exist* at the time of the second call to PostMessage()... if it
didn't, how would the first message get through? It seems wrong to me that
you have to use Sleep() even when the message queue exists!?

<no...@none.com> wrote in message news:uIQX$aGoCHA.1600@TK2MSFTNGP11...

Randy

unread,
Dec 10, 2002, 12:14:52 PM12/10/02
to
> It seems wrong to me that
> you have to use Sleep() even when the message queue exists!?

It seems wrong to me too that's why I hope someone has an idea of what's
going on. Basically I had to put a Sleep(0) before every post message to
make sure it works. Although it probably doesn't hurt my peformance to do
this, it is odd and I still want to know why.

Still hoping someone knows :)


David Lowndes

unread,
Dec 10, 2002, 12:43:54 PM12/10/02
to
>If I only post one message to the thread it is fine. But if I post two
>messages right after one another the second one is lost and
>PostThreadMessage doesn't return an error.

In the processing of the first message, is your application perhaps
running a different message loop such that the second message is
getting pulled and discarded?

For instance, if you display a MessageBox or modal dialog, these have
their own message loops which will not know how to process your
message and will discard it.

Dave
--
MVP VC++ FAQ: http://www.mvps.org/vcfaq

Randy

unread,
Dec 10, 2002, 1:02:09 PM12/10/02
to
> In the processing of the first message, is your application perhaps
> running a different message loop such that the second message is
> getting pulled and discarded?
>
> For instance, if you display a MessageBox or modal dialog, these have
> their own message loops which will not know how to process your
> message and will discard it.

No MessageBoxes or modal dialogs exist when this message is posted. And that
doesn't explain why the Sleep(0) makes it work :(


Jay Nabonne

unread,
Dec 10, 2002, 1:19:23 PM12/10/02
to

"Randy" <z...@somewhere.com> wrote in message
news:u1wYZOGoCHA.948@TK2MSFTNGP10...
> I appear to be losing messages posted using PostThreadMessage. I have a
> worker thread created that fetches messages using GetMessage. I also know
> that the message queue is created since I waited for it to be created
using
> a synchronization event.
>
> If I only post one message to the thread it is fine. But if I post two
> messages right after one another the second one is lost and
> PostThreadMessage doesn't return an error.
>
> Example.
>
> PostThreadMessage(somemessage); //works
>
> Example2.
>
> PostThreadMessage(somemessage);
> PostThreadMessage(somemessage2);
>
> The second message in example2 seems to disappear and PostThreadMessage
> doesn't fail. However this causes it to work.
>
> Example3.
> Sleep(0);
> PostThreadMessage(somemessage);
> PostThreadMessage(somemessage2);
>

Can you post the message loop code?

Jay


Randy

unread,
Dec 10, 2002, 2:02:29 PM12/10/02
to
> Can you post the message loop code?

Sure.

MSG msg; //used to hold the message retrieved from queue
char* buffer; //buffer passed in with message
int* size; //size passed in with message

ZeroMemory(&msg, sizeof(msg));

//Use peek message to force the message queue to be created
//Once it is created set the event showing it has been created
PeekMessage(&msg, NULL, UWM_WRITE_DATA, UWM_WRITE_DATA, PM_NOREMOVE);
SetEvent(thread_event);

//Loop until a WM_QUIT message is received
while(GetMessage(&msg, NULL, 0, 0))
{
if(msg.message == UWM_WRITE_DATA)
{
//if the message is a write message write the buffer to the com
port
//and deallocate the memory
size = (int*)msg.lParam;
buffer = (char*)msg.wParam;
if(*size < SpaceInTransmitBuffer(myport))
PutPacket(myport, *size, buffer);
delete []buffer;
delete size;
ZeroMemory(&msg, sizeof(msg));
}
}

//Loop while there are still messages in the message queue to make sure
//all data is written and deleted
while(PeekMessage(&msg, NULL, UWM_WRITE_DATA, UWM_WRITE_DATA,
PM_REMOVE))
{
if(msg.message == UWM_WRITE_DATA)
{
size = (int*)msg.lParam;
buffer = (char*)msg.wParam;
if(*size < SpaceInTransmitBuffer(myport))
PutPacket(myport, *size, buffer);
delete []buffer;
delete size;
}
}


Jay Nabonne

unread,
Dec 10, 2002, 3:05:46 PM12/10/02
to

"Randy" <z...@somewhere.com> wrote in message
news:u1wYZOGoCHA.948@TK2MSFTNGP10...

Just curious: how are you determining whether a message is being received or
not? Are you using TRACE? I've had TRACE's go off into the ether unless a
Sleep is done occassionally.

Just in case...

Jay


Randy

unread,
Dec 10, 2002, 3:40:32 PM12/10/02
to
> Just curious: how are you determining whether a message is being received
or
> not? Are you using TRACE? I've had TRACE's go off into the ether unless a
> Sleep is done occassionally.

Well I'm not using trace I'm not familiar with it, but I've stepped through
the debugger, and also the data with that message is never written out to
the comport, i can monitor it. Also if that message isn't processed I will
get memory leaks and I delete the memory if PostThreadMessage fails but it
doesn't so I get leaks.


Jay Nabonne

unread,
Dec 10, 2002, 3:44:57 PM12/10/02
to

"Randy" <z...@somewhere.com> wrote in message
news:u4qlnwIoCHA.2280@TK2MSFTNGP12...

Ok. Just a shot. And it definitely sounds like it's dropped (because of the
leaks).
Do you know if it's the first or second message that goes missing?

Jay


Jay Nabonne

unread,
Dec 10, 2002, 3:49:25 PM12/10/02
to

"Randy" <z...@somewhere.com> wrote in message
news:#XIy05HoCHA.2440@TK2MSFTNGP11...

This all looks ok (actually, it looks quite nice).

1) Does SpaceInTransmitBuffer or PutPacket use any sort of COM (implied
message loop)?
2) I'm assuming the threads wait for thread_event to be set initially before
posting?
3) If you comment out code (like all the processing code, short of the
delete's) does it then work?

Jay


Randy

unread,
Dec 10, 2002, 3:53:10 PM12/10/02
to
> Do you know if it's the first or second message that goes missing?

I'm 100% sure its the second message. For instance this works.

PostThreadMessage(message1); //posted
PostThreadMessage(message2); //not posted
PostThreadMessage(message2); //posted

One more example the second one is not getting posted, otherwise the 3 post
would gripe because its trying to delete memory that is no longer on the
heap.

Jay Nabonne

unread,
Dec 10, 2002, 4:03:33 PM12/10/02
to

"Randy" <z...@somewhere.com> wrote in message
news:eG8kr3IoCHA.1600@TK2MSFTNGP11...

Makes sense.

I have to ask... :) Initially I saw something like the above and thought you
were just short-handing the parameters for PostThreadMessage. Is that the
case (the PostThreadMessage I know about takes four parameters), as opposed
to a function that only takes one parameter? If it's indeed a function that
only takes 1 param, is that something of yours?

Jay (Grappling in the dark)


Randy

unread,
Dec 10, 2002, 5:09:42 PM12/10/02
to
> I have to ask... :) Initially I saw something like the above and thought
you
> were just short-handing the parameters for PostThreadMessage. Is that the
> case (the PostThreadMessage I know about takes four parameters), as
opposed
> to a function that only takes one parameter? If it's indeed a function
that
> only takes 1 param, is that something of yours?
>
> Jay (Grappling in the dark)

Yeah I was just sort of writing psuedo code to just get the message across
:). The actual call would look more like this

PostThreadMessage(writerthreadid, UWM_WRITE_DATA, (WPARAM)buffer,
(LPARAM)size));


Randy

unread,
Dec 10, 2002, 5:13:22 PM12/10/02
to
> 1) Does SpaceInTransmitBuffer or PutPacket use any sort of COM (implied
> message loop)?
> 2) I'm assuming the threads wait for thread_event to be set initially
before
> posting?
> 3) If you comment out code (like all the processing code, short of the
> delete's) does it then work?

Yes they wait on that event to be set thats the whole point :). I may try
commenting that stuff out but it could take a bit to retest :).


Tom Stewart

unread,
Dec 11, 2002, 8:44:06 AM12/11/02
to
Out of curiosity, what platform is this happening on? We've seen something
(probably completely unrelated, but...) on Win98 where a winsock related
message appears to be getting dropped. All NT based platforms are fine. But
it's not a msg we send, so the problem could be on the sending side.

--
Tom

"Randy" <z...@somewhere.com> wrote in message

news:uU#bciJoCHA.1868@TK2MSFTNGP12...

Randy

unread,
Dec 11, 2002, 10:30:25 AM12/11/02
to
It's happening in XP.


Randy

unread,
Dec 11, 2002, 1:43:43 PM12/11/02
to

> 3) If you comment out code (like all the processing code, short of the
> delete's) does it then work?

I change the part of the loop with the processing to the following code and
now it seems to work!! But I can't comment that out and it still doesn't
explain why it doesn't catch that second message when it isn't commented
out, or why when a Sleep(0) precedes the Posts that it works.

Argh!

if(msg.message == UWM_WRITE_DATA)
{
//if the message is a write message write the buffer to the
comport
//and deallocate the memory
size = (int*)msg.lParam;
buffer = (char*)msg.wParam;

//if(*size < SpaceInTransmitBuffer(myport))
//PutPacket(myport, *size, buffer);

Jay Nabonne

unread,
Dec 11, 2002, 1:53:27 PM12/11/02
to

"Randy" <z...@somewhere.com> wrote in message
news:O3Ve$TUoCHA.1608@TK2MSFTNGP10...

>
> > 3) If you comment out code (like all the processing code, short of the
> > delete's) does it then work?
>
> I change the part of the loop with the processing to the following code
and
> now it seems to work!! But I can't comment that out and it still doesn't
> explain why it doesn't catch that second message when it isn't commented
> out, or why when a Sleep(0) precedes the Posts that it works.
>
> Argh!
>

Now comes the fun. :) Selectively comment in the code, process of divide and
conquer, to find the place that is causing the drop. For example, comment in
the line for SpaceInTransmitBuffer(myport) and see if it then fails again.
If it does, go into SpaceInTransmitBuffer and begin disabling code until it
again works; then uncomment code until it fails, dive further in etc. If
not, try the PutPacket call. Eventually, you'll find the code that directly
causes your problem.

Not pretty, but patience will win out.

Jay


Randy

unread,
Dec 11, 2002, 2:02:50 PM12/11/02
to
I already know that it is the PutPacket call but thats in a serial
communications library that I don't have access too :(. I don't want to have
to hook the messages either though. Any ideas?


Jay Nabonne

unread,
Dec 11, 2002, 2:37:13 PM12/11/02
to

"Randy" <z...@somewhere.com> wrote in message
news:#GQBreUoCHA.2636@TK2MSFTNGP11...

Well, here's one:

1) Control when messages can be put posted (via a critical section or
something). Threads must grab the critical section before posting a message.
At the worst, you serialize access to the queue, but Windows is doing that
anyway, so I don't know if you'll have a performance hit.
2) When GetMessage gives you a new message, grab the critical section so the
threads can't post more.
3) Pull all the messages at once out of the queue and put them in a local
array (while PeekMessage(...) blah, blah).
4) Call PutPacket for each message in your local buffer. Since you pulled
all the messages out of the queue, there should be none for PutPacket to
eat; and since you disabled message posting, you also won't have any posted
while PutPacket is happening.
5) Renable posting and loop back to GetMessage.

Another option: don't use the message queue to transport your data. Use a
separate, properly synchronized queue to hold the data. The posted message
would simply be "hey, go look in the queue for data". You still need to
serialize access to the data, but the queue won't need to be locked while
PutPacket is happening. (Or don't use the message queue at all; use a
semaphore. Standard producer/consumer model.)

Jay


LiquidJ

unread,
Dec 12, 2002, 8:36:10 AM12/12/02
to

"Jay Nabonne" <j...@rightagain.com> wrote in message
news:#wdDxyUoCHA.2312@TK2MSFTNGP09...

>
> "Randy" <z...@somewhere.com> wrote in message
> news:#GQBreUoCHA.2636@TK2MSFTNGP11...
> > I already know that it is the PutPacket call but thats in a serial
> > communications library that I don't have access too :(. I don't want to
> have
> > to hook the messages either though. Any ideas?
> >
>
> Well, here's one:
>
> 1) Control when messages can be put posted (via a critical section or
> something). Threads must grab the critical section before posting a
message.
> At the worst, you serialize access to the queue, but Windows is doing that
> anyway, so I don't know if you'll have a performance hit.
> 2) When GetMessage gives you a new message, grab the critical section so
the
> threads can't post more.

Ah, ah...that's a "gotcha". There's no guarantee that the thread posting
the messages won't just acquire the critical section immediately after
releasing it, so it is likely that at some point in the execution, there
will be more than one message posted. You're going to need at least two
synchronization primitives to make this happen.

Randy

unread,
Dec 12, 2002, 11:47:09 AM12/12/02
to
Thanks for the excellent suggestions guys but I didn't have to do that, it
ends up the tech support guy for the library emailed me back and
acknowledged that they had a message pump that is supposed to pass the
messages on(which it obviously didn't :) However there was a function that
let me disable their message pump which of course fixed things.

Thanks for the help!


Jay Nabonne

unread,
Dec 12, 2002, 11:51:49 AM12/12/02
to

"LiquidJ" <replyt...@boo.yah> wrote in message
news:#eG9tNeoCHA.2208@TK2MSFTNGP12...

>
> "Jay Nabonne" <j...@rightagain.com> wrote in message
> news:#wdDxyUoCHA.2312@TK2MSFTNGP09...
> >
> > "Randy" <z...@somewhere.com> wrote in message
> > news:#GQBreUoCHA.2636@TK2MSFTNGP11...
> > > I already know that it is the PutPacket call but thats in a serial
> > > communications library that I don't have access too :(. I don't want
to
> > have
> > > to hook the messages either though. Any ideas?
> > >
> >
> > Well, here's one:
> >
> > 1) Control when messages can be put posted (via a critical section or
> > something). Threads must grab the critical section before posting a
> message.
> > At the worst, you serialize access to the queue, but Windows is doing
that
> > anyway, so I don't know if you'll have a performance hit.
> > 2) When GetMessage gives you a new message, grab the critical section so
> the
> > threads can't post more.
>
> Ah, ah...that's a "gotcha". There's no guarantee that the thread posting
> the messages won't just acquire the critical section immediately after
> releasing it, so it is likely that at some point in the execution, there
> will be more than one message posted. You're going to need at least two
> synchronization primitives to make this happen.

Of course. And it's not a problem at all. The point of the critical section
is to prevent posting when messages could get lost. It's not to enforce a
single-message protocol. In fact, read the next step:

>
>
> > 3) Pull all the messages at once out of the queue and put them in a
local
> > array (while PeekMessage(...) blah, blah).

This acknowledges that there could be more than one message in the queue.
And in order to prevent them being lost by a message pump in the called
function, they're *all* pulled out and stored locally before any processing
happens.

> > 4) Call PutPacket for each message in your local buffer. Since you
pulled
> > all the messages out of the queue, there should be none for PutPacket to
> > eat; and since you disabled message posting, you also won't have any
> posted
> > while PutPacket is happening.
> > 5) Renable posting and loop back to GetMessage.
> >

Jay


Norman Bullen

unread,
Dec 13, 2002, 12:11:14 PM12/13/02
to

When they say "pass the messages on" they probably mean that their
message loop calls TranslateMessage() and DispatchMesasge(), thus
passing messages on to the designated window.

Your messages, since they are created with PostThreadMessage(), have no
designated window so DispatchMessage() cannot "pass them on."

Norm

0 new messages