out of stack space when using slider

Hi all,

I've run into a problem with a data analysis interface where I sometimes (by that I mean it's hard to reproduce consistently) get an "out of stack space (too much function or macro recursion)" error.

The idea of the interface is: Dragging a slider updates the presented data, where "updating" means look up data from an image stack, process, and display. The process part can be rather time-consuming, i.e. a few hundred milliseconds.

Here's some code to illustrate:
#pragma rtGlobals=3     // Use modern global access method and strict wave access.

//EXECUTE THIS TO SHOW THE DEMO
Function start()
    //---generate dummy data
    Make/O/N=(100,100,500) images
    Setscale/I z, 0, 65535, images
    images[][][] = z
   
    //---extract the first frame
    ImageTransform/P=0 getplane images
    Wave m_imageplane
    Duplicate/O m_imageplane, currentframe
   
    //---display
    showimage()
End


Function showimage()
    Wave images

    DoWindow/F win
    if(!v_flag) //--- create window if it doesn't exist
        Wave currentframe
        NewImage/N=win currentframe
        ModifyImage/W=win currentframe ctab= {0,65535,Grays,0}
        Controlbar 50
        Slider sldFrame,pos={1,1},size={220,45},limits={0,499,1},value= 0,vert= 0,proc=sliderproc
    else //--- update frame
        //----------------
        //Here I want do do image processing which might be rather lengthy
        //In place of calculations, I sleep
        sleep/T 20
       
        Controlinfo/W=win sldFrame
        ImageTransform/P=(v_value) getplane images
        Wave m_imageplane
        Duplicate/O m_imageplane, currentframe
    endif
End

Function SliderProc(name, value, event) : SliderControl
    String name
    Variable value
    Variable event  // bit field: bit 0: value set; 1: mouse down,
                //   2: mouse up, 3: mouse moved

    NVAR/Z UPDATING_FRAME
    if(!NVAR_EXISTS(UPDATING_FRAME))
        Variable/G UPDATING_FRAME = 0
    endif

    if(UPDATING_FRAME==1)
        return 0
    endif
    UPDATING_FRAME=1
       
    if(event %& 3)
        showimage()
    endif  
   
    UPDATING_FRAME=0
   
    return 0
End



Now, when I drag the slider around for a long time (say, over 30 seconds), I suddenly end up with >20 pop up windows "out of stack space" that all appear at the same time, and I've had a hard time to fix it. Some try-catch sprinkled in on various places didn't do anything to help (although admittedly, I didn't really know what I was doing there).

Without knowing anything about the internals, I'm guessing that the event-handler for the slider puts a new instance of SliderProc in the queue every time something happens to the slider. If SliderProc doesn't finish quickly enough, I get the error. The whole business of UPDATING_FRAME in the code was supposed to get out of the function as quickly as possible, if another instance is updating already, to keep the queue clear.

Anyway, help is greatly appreciated.
Your analysis seems correct.
The easiest solution is to switch to structure based GUI procedures and use blockReentry = 1, see DisplayHelpTopic "Control Structure blockReentry Field".
Sweet, that fixed it. Thank you Thomas. I knew one day the time would come where my laziness to write structure based procs would come back at me.
Yes- the non-structure-base action procs are old technology. All the good, modern stuff goes into the structure-based procs. Abandon the non-structure procs. If we could just remove the older style we would, but that would break lots of user's code.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com