LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Problems when putting ProcessSystemEvents() in some places in the code

Hello All,
 
I am wondering if anybody has encountered a similar problem as follows:
 
To make a delay efficiently, I put the following "famous" delay without blocking function in the code
 
void DelayWithoutBlocking (double dTime)
{
     Time1 = Timer();
     while ( (Time2 - Time1) < dTime)
     {
            Time2 = Timer();
            ProcessSystemEvents ();
     }
}
 
But, when calling this function from these 2 places:
1. The Async Timer Callback
2. The windows Timer callback I created with SetTimer() function
 
I noticed that every time when executing this ProcessSystemEvents(), the PC will jump out of this piece of code to do something else in the main thread, BUT never return again, but do a new re-entrance of the callback. So the stack is always "put" at the entrance of the function, but never "released". So very quickly I got a "Stack overflow" error from CVI IDE.
 
I read some help files on some important notes on using this ProcessSystemEvents(), but never have any idea on why the PC does not return before re-enter the callback.
 
Thank you!
0 Kudos
Message 1 of 5
(3,580 Views)
Hi,
In ProcessSystemEvents() any callback function can be called.(From button, or the same timer)
if the Timer Period is less then Delay() or Wait in Timer callback,
ProcessSystemEvents() call Timer callback again(if period time is reached).

I think this is only for UI timer, not for Async Timer,

I offten use this trick:)

int CVICALLBACK CbTimer (int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{static int RunOnlyOne=0;
     switch (event)
        {
        case EVENT_TIMER_TICK:
            if (RunOnlyOne!=0)break;
            RunOnlyOne=1;

            //....
            Delay(...);ProcessSystemEvents()
                OR
            DelayWithoutBlocking()
    
            RunOnlyOne=0;
            break;
        }
    return 0;
}

PS: In DelayWithoutBlocking Time1 and Time2 variable must be declared as local for correct multithread use.
       in CbTimer RunOnlyOne variable must be declared as global or static variable.
0 Kudos
Message 2 of 5
(3,549 Views)
Thank you very much ovrabek/CZ for your hint.
 
I tried your code whlie I am afraid that it does not cure the problem. I would explain in detail the problem I encountered:
 
1. In fact, I observed that problem of "re-entrance without return" occurs only in the following 2 cases:
    a) In the Async Timer Call-back (multi-thread)
    b) In the Timer call-back I created with SetTimer(...) windows API (not CVI timer callback)
 
2. In your sample code, the variable RunOnlyOnce is declared as global/static. My problem is that in the call back, when executing the ProcessSystemEvents(), the PC will jump to some other places, but NEVER returns. In other words, the stack is pushed, but never popped. So, the RunOnlyOnce variable will continue to be 1 after that. Then the problem of stack overflow is resolved, but the callback is never executed again ...
 
Strange thing is that this phenomenon does not always occur...
0 Kudos
Message 3 of 5
(3,509 Views)
Hello,

I'v already had this kind of problem. It comes mainly from the fact that the ProcessSystemEvents() might take a long time to execute depending of which callback is going to be called.
I use this kind of "tempo" function that executes ProcessSystemEvents only each 500 iterations:

    TempsEcoule=Timer();
    TimeOut=MaDuree;
    i=0;
    while (TimeOut>0)
    {    
        OldTempsEcoule=TempsEcoule;                                                                                                                                                                      
        TempsEcoule=Timer();
        TimeOut -= (TempsEcoule-OldTempsEcoule);
         
          if (i>500)
          {
              ProcessDrawEvents();
            ProcessSystemEvents();
            i=0;
        }
       
        i++;
    }

Yop!
DanY
0 Kudos
Message 4 of 5
(3,500 Views)
Try this test code,
   Everything is how I expected.
      ProcesSystem event call callback function(myTimerFunc), and after it is finished, then return.
      As far as myTimerFunc(2 instance) finishes without calling ProcesSystem everything is in order.
      Otherwise get in to call loop and stack overflow.
  From log is also see, that tihis not occur for Async Timer.

LogFrom My PC:
****1,myAsyncTimer >start                                   
--------DelayWithoutBlocking >start
++++1,myTimerProc >start
--------DelayWithoutBlocking >start                          
++++2, myTimerProc >ReEnter - exit imediately
++++2, myTimerProc >ReEnter - exit imediately
++++2, myTimerProc >ReEnter - exit imediately
++++2, myTimerProc >ReEnter - exit imediately
++++2, myTimerProc >ReEnter - exit imediately
++++2, myTimerProc >ReEnter - exit imediately
++++2, myTimerProc >ReEnter - exit imediately
++++2, myTimerProc >ReEnter - exit imediately
++++2, myTimerProc >ReEnter - exit imediately
--------DelayWithoutBlocking <stop
++++1,myTimerProc <stop                             //return from TimerProc
++++1,myTimerProc >start                            //Next TimerProc
--------DelayWithoutBlocking >start                //start in tTimerProc
--------DelayWithoutBlocking <stop       //stop in AsyncTimer
****1,myAsyncTimer <stop                   //return from AsyncTimer     
****1,myAsyncTimer >start                  //nextAsyncTimer
--------DelayWithoutBlocking >start
++++2, myTimerProc >ReEnter - exit imediately
++++2, myTimerProc >ReEnter - exit imediately

0 Kudos
Message 5 of 5
(3,489 Views)