[bug #2937 [GRASS-dev] povray and grass

Glynn Clements glynn at gclements.plus.com
Wed May 17 06:24:37 EDT 2006


Hamish wrote:

> > There are other modules that happen to fail due to "too many nested
> > evaluations (infinite loop?)" in GUI. Those I rememeber are v.in.ogr
> > and v.extract. See http://intevation.de/rt/webrt?serial_num=2937
> > 
> > Could it be related?
> 
> I stick by my theory that tcl throws this error when it it is asked
> to process a single string repeatedly in very quick succession.

No. As the error message suggests, Tcl throws this error if the
evaluation stack gets too deep, which is normally due to infinite
recursion. E.g.:

	% proc foo {} {foo}
	% foo
	too many nested evaluations (infinite loop?)

A less obvious case is calling "update" from within an event handler
(e.g. the fileevent handler for process output). If the events occur
more rapidly than they can be processed, each call to update will
result in a nested call to the event handler.

Looking at the code for lib/gtcltk/gronsole.tcl, I notice that:

1. Gronsole::execbg registers Gronsole::file_callback as a fileevent
handler.

2. Gronsole::file_callback calls Gronsole::readout.

3. Gronsole::readout calls Gronsole::output_to_gronsole.

4. Gronsole::output_to_gronsole calls Gronsole::progress.

5. Gronsole::progress calls ProgressBar::_modify (via the widget's
_modify method).

6. ProgressBar::_modify calls update. If more output is available,
this will result in a nested call to Gronsole::file_callback, and so
on.

The last point is the problem; it should rely upon the caller to call
update if necessary (for the fileevent handler, it isn't; the update
should be performed from the event loop when Gronsole::file_callback
returns).

Removing the update from ProgressBar::_modify should eliminate the
problem. Changing it to "update idletasks" might; I'm not sure whether
file events are treated as idle events.

If you don't want to modify the BWidget library, modify the
Gronsole::file_callback function to prevent nested evaluation, e.g.

	namespace eval Gronsole {
		variable _busy
		...
		set _busy 0
	}
	
	...
	
	proc Gronsole::file_callback {path ci mark fh} {
		variable _busy
		if {$_busy} return
		set _busy 1
	
		# do stuff
	
		set _busy 0
	}

-- 
Glynn Clements <glynn at gclements.plus.com>




More information about the grass-dev mailing list