Re: [DUG] Why does this hang?

2011-08-03 Thread Ross Levis
Yeah, may be.  Currently I've replaced the ProcessMessages with
MainForm.Update which resolves the issue well enough I think.

I don't want to make major changes as it's very stable now apart from this
issue.

Thanks anyway.

-Original Message-
From: delphi-boun...@delphi.org.nz [mailto:delphi-boun...@delphi.org.nz] On
Behalf Of Paul Heinz
Sent: Wednesday, 3 August 2011 12:39 p.m.
To: NZ Borland Developers Group - Delphi List
Subject: Re: [DUG] Why does this hang?

Ross wrote: 

 The Timer.OnExecute I mentioned being run inside the loop 
 excludes some of the functions that are normally executed by 
 the timer, as these functions can not execute while we are 
 waiting on the thread.
  
 The timer cannot be idle.  It's not just updating the UI but 
 doing some other important work that is necessary to continue.
 
 I should probably mention that it's a media player with a VU 
 meter that needs updating continuously and elapsed/remaining 
 times etc.  The other thread is doing the actual playing of 
 the audio files.

Ah OK. I wondered if this was all something media/steaming related.
The slight unreliability of WM_TIMER messages is probaby fine for
updating that.
 
 The wait needs to occur when sending a command to the thread 
 to preload a track, or start playing, etc.  On occasions, a 
 procedure in the main app involves issuing several commands 
 which need to occur sequentially, hence the need to wait 
 until one command is complete.  Normally this wait is less 
 than 1 second, but it's still long enough at times to get a 
 modal dialog opened within the ProcessMessages loop, and then 
 this function hangs.

 It's been like this for years, but the occasional user comes 
 across the problem and the media player stops, generally 
 between tracks, when opening a modal dialog at the wrong moment.
 
 Preventing a modal window from opening while in this loop 
 seems to be the only solution.  The messages I was trying to 
 avoid processing were mouse clicks and keyboard keys.
 
 Any other ideas how to resolve this?

Hrmm.. Would adding a command or work queue abstraction better solve
your sequencing problem?
i.e. all 'hand-off' from the main UI thread to the streamer/working
thread is done via a queue of commands objects which that thread
processes sequentially, picking up the next one (if it exists) after it
finishes. You'd need to ensure the command queue datastructure is
thread-safe of course, but a simple TThreadList of command objects would
be fine. Assuming there are different 'kinds' of work, falls nicely onto
an inheritance hierachy of command objects with a virtual 'Execute'
method and the necessary parameter passed in their constructors.

This will completely decouple the work sequencing from the main UI
thread message loop. The main UI thread may need some ability to cancel
previously submitted commands or indicate a completion handler on
submission so as to sync the UI with the work state but that is all just
'a small matter of programming' :-)

Alternatively, it is possible to either code up your own version of
Application.ProcessMessages (or tweak the Forms.pas version as we have)
to pass an appropriate PM_QS_ mask to PeekMessage so as dispatch
everything _except_ input events (mouse or keyboard) and thus prevent UI
activity whilst 'sequencing'.

But design-wise, I think decoupling the main thread/worker thread
sequencing via a work queue is far cleaner. Still, it's your app :-)

Cheers,
  Paul.



___
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject:
unsubscribe


___
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: 
unsubscribe


Re: [DUG] Why does this hang?

2011-08-02 Thread Ross Levis
Paul,

The Timer.OnExecute I mentioned being run inside the loop excludes some of
the functions that are normally executed by the timer, as these functions
can not execute while we are waiting on the thread.
 
The timer cannot be idle.  It's not just updating the UI but doing some
other important work that is necessary to continue.

I should probably mention that it's a media player with a VU meter that
needs updating continuously and elapsed/remaining times etc.  The other
thread is doing the actual playing of the audio files.

The wait needs to occur when sending a command to the thread to preload a
track, or start playing, etc.  On occasions, a procedure in the main app
involves issuing several commands which need to occur sequentially, hence
the need to wait until one command is complete.  Normally this wait is less
than 1 second, but it's still long enough at times to get a modal dialog
opened within the ProcessMessages loop, and then this function hangs.

It's been like this for years, but the occasional user comes across the
problem and the media player stops, generally between tracks, when opening a
modal dialog at the wrong moment.

Preventing a modal window from opening while in this loop seems to be the
only solution.  The messages I was trying to avoid processing were mouse
clicks and keyboard keys.

Any other ideas how to resolve this?

Cheers.

-Original Message-
From: delphi-boun...@delphi.org.nz [mailto:delphi-boun...@delphi.org.nz] On
Behalf Of Paul Heinz
Sent: Tuesday, 2 August 2011 4:04 p.m.
To: NZ Borland Developers Group - Delphi List
Subject: Re: [DUG] Why does this hang?

Hi Ross 

 I can't remember now what problem I was having with 
 Application.ProcessMessages but this code fixed it while I 
 was testing, and had to find tune the message numbers.  I 
 failed to comment the code.  I think it had something to do 
 with other visible non-modal forms.
 
 I may have to re-instate ProcessMessages and see what the problem was.
 
 The wait loop is generally no more than 2 or 3 seconds 
 waiting for a thread command to finish, but I need the main 
 window to update continuously during this time.

Hrmm.. I don't really understand the architecture of your app, but
_usually_ threads are an attempt to NOT have to have blocking busy-wait
loops in your main UI thrad. Could your worker thread not send a message
(or use Thread.Synchronise which sends a message for you) to signal it's
completion instead?

In short, why can't you just return to the normal message loop? 

It sounds like your application has some of behaviour mode that depends
on the thread completion state but that might be better handled in the
message event handlers themselves thus completely decoupled from the
message loop itself.

Finally, it's more of a side issue but the timers you speak off which
are updating the UI - are they able to be handled as idle time events
instead or are they actually indicating timing related information to
the user?

Cheers,
  Paul.



___
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject:
unsubscribe


___
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: 
unsubscribe


Re: [DUG] Why does this hang?

2011-08-02 Thread Paul Heinz
Ross wrote: 

 The Timer.OnExecute I mentioned being run inside the loop 
 excludes some of the functions that are normally executed by 
 the timer, as these functions can not execute while we are 
 waiting on the thread.
  
 The timer cannot be idle.  It's not just updating the UI but 
 doing some other important work that is necessary to continue.
 
 I should probably mention that it's a media player with a VU 
 meter that needs updating continuously and elapsed/remaining 
 times etc.  The other thread is doing the actual playing of 
 the audio files.

Ah OK. I wondered if this was all something media/steaming related.
The slight unreliability of WM_TIMER messages is probaby fine for
updating that.
 
 The wait needs to occur when sending a command to the thread 
 to preload a track, or start playing, etc.  On occasions, a 
 procedure in the main app involves issuing several commands 
 which need to occur sequentially, hence the need to wait 
 until one command is complete.  Normally this wait is less 
 than 1 second, but it's still long enough at times to get a 
 modal dialog opened within the ProcessMessages loop, and then 
 this function hangs.

 It's been like this for years, but the occasional user comes 
 across the problem and the media player stops, generally 
 between tracks, when opening a modal dialog at the wrong moment.
 
 Preventing a modal window from opening while in this loop 
 seems to be the only solution.  The messages I was trying to 
 avoid processing were mouse clicks and keyboard keys.
 
 Any other ideas how to resolve this?

Hrmm.. Would adding a command or work queue abstraction better solve
your sequencing problem?
i.e. all 'hand-off' from the main UI thread to the streamer/working
thread is done via a queue of commands objects which that thread
processes sequentially, picking up the next one (if it exists) after it
finishes. You'd need to ensure the command queue datastructure is
thread-safe of course, but a simple TThreadList of command objects would
be fine. Assuming there are different 'kinds' of work, falls nicely onto
an inheritance hierachy of command objects with a virtual 'Execute'
method and the necessary parameter passed in their constructors.

This will completely decouple the work sequencing from the main UI
thread message loop. The main UI thread may need some ability to cancel
previously submitted commands or indicate a completion handler on
submission so as to sync the UI with the work state but that is all just
'a small matter of programming' :-)

Alternatively, it is possible to either code up your own version of
Application.ProcessMessages (or tweak the Forms.pas version as we have)
to pass an appropriate PM_QS_ mask to PeekMessage so as dispatch
everything _except_ input events (mouse or keyboard) and thus prevent UI
activity whilst 'sequencing'.

But design-wise, I think decoupling the main thread/worker thread
sequencing via a work queue is far cleaner. Still, it's your app :-)

Cheers,
  Paul.



___
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: 
unsubscribe


Re: [DUG] Why does this hang?

2011-08-01 Thread Edward Huang
Not 100% sure, but I thought that your loop will not work if the message on
top of the queue is not falling into your range, and the message would
remain on the queue (due to 'NOREMOVE' flag), and will be peeked everytime
afterwards.
 
Not sure which message MadExcept uses, it could well be outside of your
message ID range.
 
Edward

  _  

From: delphi-boun...@delphi.org.nz [mailto:delphi-boun...@delphi.org.nz] On
Behalf Of Ross Levis
Sent: Thursday, 28 July 2011 11:17 p.m.
To: 'NZ Borland Developers Group - Delphi List'
Subject: Re: [DUG] Why does this hang?



A little more info.  I have MadExcept operating and it detected The
application seems to be frozen.

 

77fa15ec ntdll.dll KiUserCallbackDispatcher

77e1567d user32.dllPeekMessageA

 

KiUserCallbackDispatcher is where it is hanging.

 

From: delphi-boun...@delphi.org.nz [mailto:delphi-boun...@delphi.org.nz] On
Behalf Of Ross Levis
Sent: Thursday, 28 July 2011 11:09 p.m.
To: 'NZ Borland Developers Group - Delphi List'
Subject: [DUG] Why does this hang?

 

I'm using the following code inside a wait loop so that most messages are
processed except for some mouse and keyboard messages (I think) which I
don't want to be processed.  It's working perfectly here but for another
user it hangs indefinitely.

 

If PeekMessage(Msg, MainForm.Handle , 0, 0, PM_NOREMOVE) and

((Msg.message  160) or ((Msg.message  264) and (Msg.message  512))

or (Msg.message  524)) then

   Application.HandleMessage;

 

I use to have an Application.ProcessMessages but this was causing a problem
which I can't remember now, and this code fixed it.

 

Cheers.

  _  

No virus found in this message.
Checked by AVG - www.avg.com
Version: 10.0.1390 / Virus Database: 1518/3797 - Release Date: 07/29/11

___
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: 
unsubscribe

Re: [DUG] Why does this hang?

2011-08-01 Thread Kyley Harris
to properly help we'd really need to have an understanding of what your wait
loop is waiting for, and how its waiting..

you are most likely causing a deadlock where the handle message is passing
it to something else that could be waiting for your wait to complete. The
handle message could be forcing your code to act out of turn..

so without knowing why you are waiting, and for what.. as well as what you
want handled the reasons could be numerous.

On Thu, Jul 28, 2011 at 11:09 PM, Ross Levis r...@stationplaylist.comwrote:

 I’m using the following code inside a wait loop so that most messages are
 processed except for some mouse and keyboard messages (I think) which I
 don’t want to be processed.  It’s working perfectly here but for another
 user it hangs indefinitely.

 ** **

 If PeekMessage(Msg, MainForm.Handle , 0, 0, PM_NOREMOVE) and

 ((Msg.message  160) or ((Msg.message  264) and (Msg.message  512))

 or (Msg.message  524)) then

Application.HandleMessage;

 ** **

 I use to have an Application.ProcessMessages but this was causing a problem
 which I can’t remember now, and this code fixed it.

 ** **

 Cheers.

 ___
 NZ Borland Developers Group - Delphi mailing list
 Post: delphi@delphi.org.nz
 Admin: http://delphi.org.nz/mailman/listinfo/delphi
 Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject:
 unsubscribe




-- 
Kyley Harris
Harris Software
+64-21-671-821
___
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: 
unsubscribe

Re: [DUG] Why does this hang?

2011-08-01 Thread Paul Heinz
Edward wrote: 

 Not 100% sure, but I thought that your loop will not work if 
 the message on top of the queue is not falling into your 
 range, and the message would remain on the queue (due to 
 'NOREMOVE' flag), and will be peeked everytime afterwards.
  
 Not sure which message MadExcept uses, it could well be 
 outside of your message ID range.

Yeah, I think Edward is likely spot on here. 

Whatever message this code is preventing from being dispatched (i.e. the
one that previously was causing an error when
Application.ProcessMessages was called instead) is sitting at the top of
the message queue and since it's not being dispatched, it will keep
being returned from PeekMessage and no other windows messages will be
being dispatched.

Windows detects hung applications on the basis of apps failing to
process WM_PAINT messages for a period of time. Now, technically,
WM_PAINT messages are not actually _sent_, they are synthesized based on
your applications dirty regions but only when the message queue is
otherwise empty but the principle is the same. If you're blocked from
processing any messages, you're blocked from processing WM_PAINT.

You might be able to force WM_PAINT calls to be pumped by clever use of
PeekMessage with the PM_QS_PAINT flag to dispacth only WM_PAINT messages
but I've never tried that.

We've modified Forms.pas to allow conditional PM_QS_ family flags to be
passed to Application.ProcessMessages to control the potential
re-entrancy issues that ProcessMessages entails. Being able to process
all outstanding messages without dispatching input is generally far
safer.

Anyway, without knowing more context, I'd be inclined to reinstate the
Application.ProcessMessages and attempt to figure out what the offending
messages that was causing the original problem rather than futzing with
the message loop. 

The Windows message loop is subtle and prone to anger :-) It also
behaves differently under Windows 7 so we had to tweak our conditional
dispatch code to avoid spurious 'hung application' issues that Windows
XP and Vista were fine with.

Essentially, if Windows 7 doesn't see an unconditional PeekMessage being
called regularly, it also consider the app to have hung, even though you
are conditionally pumping WM_PAINT and other messages. A single
unconditional PeekMessage PM_NOREMOVE will satisfy it. Go figure as to
why MS changed this.

Cheers,
  Paul.








___
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: 
unsubscribe


Re: [DUG] Why does this hang?

2011-08-01 Thread Jolyon Smith
Yep, critical to this is not what happens to the matching messages but what is 
being done (or not) with messages that don't match.

I would expect to see an 'else' which repeats the call to PeekMessage but 
without the PM_REMOVE flag.

 Edward Huang edwa...@slingshot.co.nz wrote: 

Not 100% sure, but I thought that your loop will not work if the message on top 
of the queue is not falling into your range, and the message would remain on 
the queue (due to 'NOREMOVE' flag), and will be peeked everytime afterwards.
 
Not sure which message MadExcept uses, it could well be outside of your message 
ID range.
 
Edward

From: delphi-boun...@delphi.org.nz [mailto:delphi-boun...@delphi.org.nz] On 
Behalf Of Ross Levis
Sent: Thursday, 28 July 2011 11:17 p.m.
To: 'NZ Borland Developers Group - Delphi List'
Subject: Re: [DUG] Why does this hang?

A little more info.  I have MadExcept operating and it detected “The 
application seems to be frozen.”

 

77fa15ec ntdll.dll KiUserCallbackDispatcher

77e1567d user32.dll    PeekMessageA

 

KiUserCallbackDispatcher is where it is hanging.

 

From: delphi-boun...@delphi.org.nz [mailto:delphi-boun...@delphi.org.nz] On 
Behalf Of Ross Levis
Sent: Thursday, 28 July 2011 11:09 p.m.
To: 'NZ Borland Developers Group - Delphi List'
Subject: [DUG] Why does this hang?

 

I’m using the following code inside a wait loop so that most messages are 
processed except for some mouse and keyboard messages (I think) which I don’t 
want to be processed.  It’s working perfectly here but for another user it 
hangs indefinitely.

 

If PeekMessage(Msg, MainForm.Handle , 0, 0, PM_NOREMOVE) and

((Msg.message  160) or ((Msg.message  264) and (Msg.message  512))

or (Msg.message  524)) then

   Application.HandleMessage;

 

I use to have an Application.ProcessMessages but this was causing a problem 
which I can’t remember now, and this code fixed it.

 

Cheers.

No virus found in this message.
Checked by AVG - www.avg.com
Version: 10.0.1390 / Virus Database: 1518/3797 - Release Date: 07/29/11

___
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: 
unsubscribe

Re: [DUG] Why does this hang?

2011-08-01 Thread Ross Levis
Yeah, I wondered that.  There may be a better way to run through the queue
of messages and only process those ones I permit.

 

Cheers.

 

From: delphi-boun...@delphi.org.nz [mailto:delphi-boun...@delphi.org.nz] On
Behalf Of Edward Huang
Sent: Monday, 1 August 2011 8:51 p.m.
To: 'NZ Borland Developers Group - Delphi List'
Subject: Re: [DUG] Why does this hang?

 

Not 100% sure, but I thought that your loop will not work if the message on
top of the queue is not falling into your range, and the message would
remain on the queue (due to 'NOREMOVE' flag), and will be peeked everytime
afterwards.

 

Not sure which message MadExcept uses, it could well be outside of your
message ID range.

 

Edward

 

  _  

From: delphi-boun...@delphi.org.nz [mailto:delphi-boun...@delphi.org.nz] On
Behalf Of Ross Levis
Sent: Thursday, 28 July 2011 11:17 p.m.
To: 'NZ Borland Developers Group - Delphi List'
Subject: Re: [DUG] Why does this hang?

A little more info.  I have MadExcept operating and it detected The
application seems to be frozen.

 

77fa15ec ntdll.dll KiUserCallbackDispatcher

77e1567d user32.dllPeekMessageA

 

KiUserCallbackDispatcher is where it is hanging.

 

From: delphi-boun...@delphi.org.nz [mailto:delphi-boun...@delphi.org.nz] On
Behalf Of Ross Levis
Sent: Thursday, 28 July 2011 11:09 p.m.
To: 'NZ Borland Developers Group - Delphi List'
Subject: [DUG] Why does this hang?

 

I'm using the following code inside a wait loop so that most messages are
processed except for some mouse and keyboard messages (I think) which I
don't want to be processed.  It's working perfectly here but for another
user it hangs indefinitely.

 

If PeekMessage(Msg, MainForm.Handle , 0, 0, PM_NOREMOVE) and

((Msg.message  160) or ((Msg.message  264) and (Msg.message  512))

or (Msg.message  524)) then

   Application.HandleMessage;

 

I use to have an Application.ProcessMessages but this was causing a problem
which I can't remember now, and this code fixed it.

 

Cheers.

  _  

No virus found in this message.
Checked by AVG - www.avg.com
Version: 10.0.1390 / Virus Database: 1518/3797 - Release Date: 07/29/11

___
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: 
unsubscribe

Re: [DUG] Why does this hang?

2011-08-01 Thread Ross Levis
I just did that and worked out what the problem is.  It is to do with modal
windows opened while inside my wait loop executing ProcessMessages.

My main form has a timer which needs to continue running at all times.  This
timer is running various functions mostly to do with updating VCL controls.
At certain times, it needs to wait for perhaps a few seconds for a thread to
finish and requires ProcessMessages so the main window continues to update.
I also run the Timer.OnExecute procedure from within this loop so nothing
appears paused.

Generally this works fine when a modal window is loaded, but if I happen to
load a modal window like an open file dialog while inside this wait loop,
ProcessMessages hangs.  If I load the modal window 1 second earlier, then
the wait loop works fine including ProcessMessages.

Likely the ProcessMessages is what caused the modal dialog to load, and the
routine then hangs for a reason I'm sure one of you will know.

Any way to resolve this?

Cheers.


-Original Message-
From: Ross Levis [mailto:r...@stationplaylist.com] 
Sent: Tuesday, 2 August 2011 1:54 a.m.
To: 'NZ Borland Developers Group - Delphi List'
Subject: RE: [DUG] Why does this hang?

I can't remember now what problem I was having with
Application.ProcessMessages but this code fixed it while I was testing, and
had to find tune the message numbers.  I failed to comment the code.  I
think it had something to do with other visible non-modal forms.

I may have to re-instate ProcessMessages and see what the problem was.

The wait loop is generally no more than 2 or 3 seconds waiting for a thread
command to finish, but I need the main window to update continuously during
this time.

Ross.

-Original Message-
From: delphi-boun...@delphi.org.nz [mailto:delphi-boun...@delphi.org.nz] On
Behalf Of Paul Heinz
Sent: Monday, 1 August 2011 9:30 p.m.
To: edwa...@bigfoot.com; NZ Borland Developers Group - Delphi List
Subject: Re: [DUG] Why does this hang?

Edward wrote: 

 Not 100% sure, but I thought that your loop will not work if 
 the message on top of the queue is not falling into your 
 range, and the message would remain on the queue (due to 
 'NOREMOVE' flag), and will be peeked everytime afterwards.
  
 Not sure which message MadExcept uses, it could well be 
 outside of your message ID range.

Yeah, I think Edward is likely spot on here. 

Whatever message this code is preventing from being dispatched (i.e. the
one that previously was causing an error when
Application.ProcessMessages was called instead) is sitting at the top of
the message queue and since it's not being dispatched, it will keep
being returned from PeekMessage and no other windows messages will be
being dispatched.

Windows detects hung applications on the basis of apps failing to
process WM_PAINT messages for a period of time. Now, technically,
WM_PAINT messages are not actually _sent_, they are synthesized based on
your applications dirty regions but only when the message queue is
otherwise empty but the principle is the same. If you're blocked from
processing any messages, you're blocked from processing WM_PAINT.

You might be able to force WM_PAINT calls to be pumped by clever use of
PeekMessage with the PM_QS_PAINT flag to dispacth only WM_PAINT messages
but I've never tried that.

We've modified Forms.pas to allow conditional PM_QS_ family flags to be
passed to Application.ProcessMessages to control the potential
re-entrancy issues that ProcessMessages entails. Being able to process
all outstanding messages without dispatching input is generally far
safer.

Anyway, without knowing more context, I'd be inclined to reinstate the
Application.ProcessMessages and attempt to figure out what the offending
messages that was causing the original problem rather than futzing with
the message loop. 

The Windows message loop is subtle and prone to anger :-) It also
behaves differently under Windows 7 so we had to tweak our conditional
dispatch code to avoid spurious 'hung application' issues that Windows
XP and Vista were fine with.

Essentially, if Windows 7 doesn't see an unconditional PeekMessage being
called regularly, it also consider the app to have hung, even though you
are conditionally pumping WM_PAINT and other messages. A single
unconditional PeekMessage PM_NOREMOVE will satisfy it. Go figure as to
why MS changed this.

Cheers,
  Paul.








___
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject:
unsubscribe


___
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: 
unsubscribe


Re: [DUG] Why does this hang?

2011-08-01 Thread Ross Levis
I can't remember now what problem I was having with
Application.ProcessMessages but this code fixed it while I was testing, and
had to find tune the message numbers.  I failed to comment the code.  I
think it had something to do with other visible non-modal forms.

I may have to re-instate ProcessMessages and see what the problem was.

The wait loop is generally no more than 2 or 3 seconds waiting for a thread
command to finish, but I need the main window to update continuously during
this time.

Ross.

-Original Message-
From: delphi-boun...@delphi.org.nz [mailto:delphi-boun...@delphi.org.nz] On
Behalf Of Paul Heinz
Sent: Monday, 1 August 2011 9:30 p.m.
To: edwa...@bigfoot.com; NZ Borland Developers Group - Delphi List
Subject: Re: [DUG] Why does this hang?

Edward wrote: 

 Not 100% sure, but I thought that your loop will not work if 
 the message on top of the queue is not falling into your 
 range, and the message would remain on the queue (due to 
 'NOREMOVE' flag), and will be peeked everytime afterwards.
  
 Not sure which message MadExcept uses, it could well be 
 outside of your message ID range.

Yeah, I think Edward is likely spot on here. 

Whatever message this code is preventing from being dispatched (i.e. the
one that previously was causing an error when
Application.ProcessMessages was called instead) is sitting at the top of
the message queue and since it's not being dispatched, it will keep
being returned from PeekMessage and no other windows messages will be
being dispatched.

Windows detects hung applications on the basis of apps failing to
process WM_PAINT messages for a period of time. Now, technically,
WM_PAINT messages are not actually _sent_, they are synthesized based on
your applications dirty regions but only when the message queue is
otherwise empty but the principle is the same. If you're blocked from
processing any messages, you're blocked from processing WM_PAINT.

You might be able to force WM_PAINT calls to be pumped by clever use of
PeekMessage with the PM_QS_PAINT flag to dispacth only WM_PAINT messages
but I've never tried that.

We've modified Forms.pas to allow conditional PM_QS_ family flags to be
passed to Application.ProcessMessages to control the potential
re-entrancy issues that ProcessMessages entails. Being able to process
all outstanding messages without dispatching input is generally far
safer.

Anyway, without knowing more context, I'd be inclined to reinstate the
Application.ProcessMessages and attempt to figure out what the offending
messages that was causing the original problem rather than futzing with
the message loop. 

The Windows message loop is subtle and prone to anger :-) It also
behaves differently under Windows 7 so we had to tweak our conditional
dispatch code to avoid spurious 'hung application' issues that Windows
XP and Vista were fine with.

Essentially, if Windows 7 doesn't see an unconditional PeekMessage being
called regularly, it also consider the app to have hung, even though you
are conditionally pumping WM_PAINT and other messages. A single
unconditional PeekMessage PM_NOREMOVE will satisfy it. Go figure as to
why MS changed this.

Cheers,
  Paul.








___
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject:
unsubscribe


___
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: 
unsubscribe


Re: [DUG] Why does this hang?

2011-08-01 Thread Paul Heinz
Hi Ross 

 I can't remember now what problem I was having with 
 Application.ProcessMessages but this code fixed it while I 
 was testing, and had to find tune the message numbers.  I 
 failed to comment the code.  I think it had something to do 
 with other visible non-modal forms.
 
 I may have to re-instate ProcessMessages and see what the problem was.
 
 The wait loop is generally no more than 2 or 3 seconds 
 waiting for a thread command to finish, but I need the main 
 window to update continuously during this time.

Hrmm.. I don't really understand the architecture of your app, but
_usually_ threads are an attempt to NOT have to have blocking busy-wait
loops in your main UI thrad. Could your worker thread not send a message
(or use Thread.Synchronise which sends a message for you) to signal it's
completion instead?

In short, why can't you just return to the normal message loop? 

It sounds like your application has some of behaviour mode that depends
on the thread completion state but that might be better handled in the
message event handlers themselves thus completely decoupled from the
message loop itself.

Finally, it's more of a side issue but the timers you speak off which
are updating the UI - are they able to be handled as idle time events
instead or are they actually indicating timing related information to
the user?

Cheers,
  Paul.



___
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: 
unsubscribe


[DUG] Why does this hang?

2011-07-28 Thread Ross Levis
I'm using the following code inside a wait loop so that most messages are
processed except for some mouse and keyboard messages (I think) which I
don't want to be processed.  It's working perfectly here but for another
user it hangs indefinitely.

 

If PeekMessage(Msg, MainForm.Handle , 0, 0, PM_NOREMOVE) and

((Msg.message  160) or ((Msg.message  264) and (Msg.message  512))

or (Msg.message  524)) then

   Application.HandleMessage;

 

I use to have an Application.ProcessMessages but this was causing a problem
which I can't remember now, and this code fixed it.

 

Cheers.

___
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: 
unsubscribe