LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Is it possible to enter function twice before exiting?

Solved!
Go to solution

I have an executable that includes a user interface, and on the user interface, there are 2 Timer controls, each using the same callback function, but each timer is set to a different tick rate.  The reason for coding this way is not important, but the fact it is coded that way is necessary to know in addressing the question.

 

The executable is single threaded, thus it is expected that all execution flow operates sequentially.  However, we have seen evidence, in a log file, that the callback function for the two timers is being entered twice before exiting. 

 

Excerpt of logfile:

04 21 2014 12:29:03: Leaving  <- - 34
04 21 2014 12:29:03: Entering -> - 29
04 21 2014 12:29:03: Leaving  <- - 29
04 21 2014 12:29:03: Entering -> - 24
04 21 2014 12:29:04: Leaving  <- - 34
04 21 2014 12:29:04: Entering -> - 30
04 21 2014 12:29:04: Entering -> - 28
04 21 2014 12:29:04: Leaving  <- - 30
04 21 2014 12:29:04: Leaving  <- - 29
04 21 2014 12:29:04: Entering -> - 30
04 21 2014 12:29:04: Leaving  <- - 28
04 21 2014 12:29:04: Entering -> - 31
04 21 2014 12:29:04: Leaving  <- - 28
04 21 2014 12:29:04: Entering -> - 30

Where fields are: date/time - message - duration (using duration = clock();) between calls to logging function.

 

I can understand that two timers not set to identical  tick periods will eventually conflict, and perhaps both generate EVENT_TIMER_TICKs before either event is handled, but I would not expect to see execution flow into the same C function (in this case our callback) twice before execution flow of first call exits.

 

Given there is no application level multi-threading, and there is no recursion,  How can this happen? i.e., are there internally launched Threading or Fibers deployed upon invoking a UI timer control? (I always assumed from the documentation Timer Controls operated strictly in the primary thread, unlike, Async Timers for example, which do run in a separate thread)

0 Kudos
Message 1 of 6
(4,699 Views)

Think about the following scenario: The scheduler interupts the first timer call to schedule to an OS internal task. When ready with with this task, the second timer needs to be executed.  What to do next: finish the first timer function or start the second one ? 

0 Kudos
Message 2 of 6
(4,675 Views)

It's not necessarily the case that your timer event is being called in different threads (you can log the output of the CmtGetCurrentThreadID function to confirm this).

 

The most likely situation is that your timer events are being nested. A single timer control is guaranteed to never nest its events, but since you have more than one timer, it is possible that that can happen. Are you possibly processing events inside your callback function? (calls to ProcessSystemEvents, GetUserEvent, RunUserInterface, for example)

 

Luis

0 Kudos
Message 3 of 6
(4,655 Views)

Luis,

 

Indeed, we are calling ProcessDrawEvents and ProcessSystemEvents in that callback. 

 

But timer events being nested  does not necessarily equate to execution flow entering a function twice before leaving, does it?  Is there some NI documentation you are drawing from that you can link to me?  I am especially interested in something referencing nested timer loops, as well as A single timer control is guaranteed to never nest.

 

As an aside, up until I observed this behavior just a few days ago, I would have said it was not possible for a C function to have execution flow entering twice before leaving once.

 

Thanks

0 Kudos
Message 4 of 6
(4,647 Views)
Solution
Accepted by topic author AndyWillison

"Timer events being nested" does equate to execution flow entering a function twice before leaving. Basically, it's the same thing as basic recursion: while you're inside one function, you call that same function. The only difference between this case and basic recursion is that the recursion call is implicit (via ProcessSystemEvents) and not explicit. But the end result is the same.

 

I'm sorry, I couldn't find any documentation that says that individual timers are not reentrant (i.e. cannot nest). I was speaking from what I know, but I couldn't find it documented anywhere.

 

The only reason you have reentrancy in your case is because you have two timers both using the same callback. If you assigned different callbacks to them, then you should be able to rely on no reentrancy for either function.

Message 5 of 6
(4,621 Views)

Luis,

 

Thanks,  That just about covers it.  BTW, the additional UI timer in this case was a mistake, discovered (or introduced) while revising an existing project.  As soon as it was discovered, we recongnized the conflict in callback function with the other UI timer, and deleted it.  But the mystery of multiple entry into a function, although suspicious the timer could have caused it, was still a curiosity.  If you do discover documentation surrounding this phenomena, please post it on this thread.

 

Thanks

0 Kudos
Message 6 of 6
(4,586 Views)