Monday, January 14, 2013

Reentrancy of events

Not very long ago, I encountered a weird situation which took lots of time to resolve (yes, call me stupid): a measurement device delivered data to my program at irregular intervals by triggering an event which took the new value, added it to a FIFO structure and redrew the corresponding graph.

This worked nice, however, every now and then parts of the drawing disappeared (I used RChart for displaying the graph). The problem was, of course, that the glitch occurred only infrequently, so debugging was in fact almost impossible (how can you the detect the condition of not drawing parts of a graph?).

In such situations, I did what I call "debugging by meditation" (;-): I slept over it, hoping that my brain finds a solution while being asleep.....

And the solution was simple enough: the event to redraw the graph was called a second time before the previous call had been finished (re-entrant call), clearing parts of the graph. So I simply created the following program structure to block re-entrant calls of the drawing routine:


var
  IsProcessing: boolean; // (private variable of the form)

...
...
...

procedure OnDataTrigger (Sender: TObject; newdat: double);

begin
.... // collect the data (not shown here)

if not Processing then
  begin
  IsProcessing := true;

  .... // display the data

  IsProcessing := false;
  end;
end;
... and the glitches were gone!

A final remark: in my case it was a little bit more complicated, because of additional restrictions of the measurement device. So I used the event to collect the data in an array and called the drawing routine only when enough data were available...

Yes, and the very last remark: do not forget to initialize the "IsProcessing" variable to FALSE.

No comments:

Post a Comment