Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2008-10

fpSelect() with very small timeout?

4 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Graeme Geldenhuys

Hi,

Below is some code I use in fpGUI-X11's main event loop. When I played around with multithreading, I wrote a simple application, created 4 threads that each update there own ProgressBar. I noticed that if I don't move the mouse, the ProgressBar gets updated slowly. And when I move the mouse over the form, the updates seem more smooth and frequent. The default timeout for fpSelect was 1000ms. I decreased that to 50ms and now all GUI updates from the 4 threads are smooth. With or without moving the mouse. CPU load also doesn't seem to be affected - it's still between 0-1% load.

Is there any downsides I don't know about when using fpSelect() with such a small timeout?

begin
  xfd := XConnectionNumber(display);
  XFlush(display);
  needToWait := True;
  if XPending(display) > 0 then // We have a X message to process
  begin
    XNextEvent(display, @ev);
    needToWait := False;
  end;
  if needToWait then  // No X messages to process (we are idle). So do
a timeout wait
  begin
    if Assigned(FOnIdle) then
      OnIdle(self);
    fpFD_ZERO(rfds);
    fpFD_SET(xfd, rfds);
    r := fpSelect(xfd + 1, @rfds, nil, nil, 50);    // 50ms timeout
    if r  0 then  // We got a X event or the timeout happened
      XNextEvent(display, @ev)
    else
      Exit; // nothing further to do here!
  end;
[... if we get here, we have X events to handle....]
end;

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Martin Schreiber
to Graeme Geldenhuys
Graeme Geldenhuys wrote 12 lines
Hi, Below is some code I use in fpGUI-X11's main event loop. When I played around with multithreading, I wrote a simple application, created 4 threads that each update there own ProgressBar. I noticed that if I don't move the mouse, the ProgressBar gets updated slowly. And when I move the mouse over the form, the updates seem more smooth and frequent. The default timeout for fpSelect was 1000ms. I decreased that to 50ms and now all GUI updates from the 4 threads are smooth. With or without moving the mouse. CPU load also doesn't seem to be affected - it's still between 0-1% load.

[...]
You could send a wakeup message to the X event queue if a widget has been invalidated instead of polling. See MSEgui lib/common/msegui.pas tguiapplication.invalidated and the postevent infrastructure for an example.

Martin

Graeme Geldenhuys
to Martin Schreiber
Martin Schreiber wrote
[...] You could send a wakeup message to the X event queue if a widget has been invalidated instead of polling. See MSEgui lib/common/msegui.pas tguiapplication.invalidated and the postevent infrastructure for an example.

Thanks Martin. I take it, your method would be a bit more efficient than polling? Or wouldn't it make much difference because the event loop keeps looping anyway?

For example: Using the wakeup event, it will simply break out of the message handling a bit quicker. "if XPending(display) > 0" would have a "else" part where it fires the OnIdle event and then breaks out. Skipping (or making redundant) the "if needToWait ..." block of code.

Either way, I like your idea.

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Martin Schreiber
to Graeme Geldenhuys
Graeme Geldenhuys wrote 11 lines
On Mon, Oct 20, 2008 at 10:19 AM, Martin Schreiber wrote: > [...] > You could send a wakeup message to the X event queue if a widget has been > invalidated instead of polling. See MSEgui lib/common/msegui.pas > tguiapplication.invalidated and the postevent infrastructure for an > example. Thanks Martin. I take it, your method would be a bit more efficient than polling? Or wouldn't it make much difference because the event loop keeps looping anyway?

The MSEgui main event loop waits on a poll() call for X messages. There is a emergency timeout of one second because the new xcb library seems to have a problem by sometimes not to deliver client messages in time.

Show quoted text 5 lines
For example: Using the wakeup event, it will simply break out of the message handling a bit quicker. "if XPending(display) > 0" would have a "else" part where it fires the OnIdle event and then breaks out. Skipping (or making redundant) the "if needToWait ..." block of code.

No, the purpose of the wakeup message is to terminate the poll() call. Updating the widgets and call of OnIdle will be done before poll() is called again.

Martin