LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Event structure mischief.... suggestions?

Solved!
Go to solution

Thanks for the suggestion. I forgot to mention that I am registering for all these events dynamically because I placed my Event Structure in a subVI.

Before you say anything, I only have one register for events per event structure, of which I have one per asynchronous VI; I am aware of the race condition you can get when you split a single Event Registration Refnum wire to two Event structures.

 

My code doesn't have any problem returning to the event structure, in fact, it continues to time out, even while front panel events are supposed to be being triggered. It's almost as if I have that race condition, but I do not see how because of the above precautions... 

0 Kudos
Message 11 of 23
(2,254 Views)

@smallmediumlarge wrote:
Before you say anything, I only have one register for events per event structure, of which I have one per asynchronous VI; I am aware of the race condition you can get when you split a single Event Registration Refnum wire to two Event structures.

That's not actually a race condition, but another type of bug, but it's good that you're aware of it, because it's definitely something to be avoided and was one of the guesses I had for what's going on in your code.

 

The other obvious guess is a race condition - the registration is the action which tells the event system to add events to this specific event queue. If you register after the stop event has been generated, it won't be added to that queue and the event structure will never see it.

 

Another option is that you're manipulating the event registration refnum in some way after registering (such as by changing the registration or maybe clearing buffers). This is legitimate, but can sometimes have results you don't expect. Jack Dunaway had a good presentation on events which probably covers this and there's video of it here - https://lavag.org/topic/16091-ni-week-2012-videos (follow the FTP login instructions and look at the NIWeek 2013 presentations).

 

Without looking at code, though, this is all just a guess.


___________________
Try to take over the world!
Message 12 of 23
(2,240 Views)

Hi tst, 

 

Yeah now that I think about it, I guess it doesn't fit the definition of "race condition"; I just meant that it can lead to unexpected behavior in your code because you have two 

event structures competing to access the same event queue.

 

Actually, there is a coercion dot with the event registration refnum because I typedef-ed it. Maybe that's the issue?

 

I am attaching an excerpt from my code. It is a bit sloppy, because I still need to convert data passing between my VIs to an event-based architecture, and am thus relying on polling, and it definitely will not execute without the rest of the application.. however maybe you guys could still spot what I'm doing wrong with regards to the event registration.

0 Kudos
Message 13 of 23
(2,224 Views)

@smallmediumlarge wrote:

I just meant that it can lead to unexpected behavior in your code because you have two event structures competing to access the same event queue.

 


Each event structure has their own event queue, and, if they have common events, each event structure will fire it. There is no "competition".

 

For example, I might have two event structures that listen for a value change of a boolean. One event structure will do some recalculation based on the new value while another event structure would change the range of a scale or the visibility of certain controls. Both will execute when the boolean is changed by the user. I typically have a parallel loop that exclusively handles cosmetic UI stuff.

 

Another very simple example of two event structure listening for the same event can be found here.  (from 2005!) 

Message 14 of 23
(2,216 Views)

My impression was that with dynamic event registration each event registration refnum has a separate event queue associated with it. 

 

Therefore if  ( I didn't) you wire the same event registration refnum to two separate event structures you end up having both event structures competing for the same event queue, which is why you should never do it.

 

I think this is different from having two event structures separately registered for the same event, in which case they both have their own separate event queue from which they pull the events. 

 

 

Support: https://www.ni.com/docs/en-US/bundle/labview/page/dynamically-registering-for-events.html

0 Kudos
Message 15 of 23
(2,205 Views)

Yes, I haven't looked at your code. Just wanted to make sure your statement is not taken out of context.

0 Kudos
Message 16 of 23
(2,192 Views)

@smallmediumlarge wrote:

 

I am attaching an excerpt from my code. It is a bit sloppy, because I still need to convert data passing between my VIs to an event-based architecture, and am thus relying on polling, and it definitely will not execute without the rest of the application.. however maybe you guys could still spot what I'm doing wrong with regards to the event registration.


When attaching a huge hierarchy of  VIs, please tell us the name and location of the toplevel VI. We don't want to keep guessing and searching. Thanks.

0 Kudos
Message 17 of 23
(2,175 Views)

I'm sorry, I was kind of in a rush and forgot to include that vital info. Top Level is Simple_Graph.vi inside the Graph folder.

0 Kudos
Message 18 of 23
(2,168 Views)
Solution
Accepted by topic author smallmediumlarge

You do understand the difference between the event ref and the registration ref, but it should be pointed out that the issue of multiple structures using the same reg ref is more complicated than "only one will read". That would indeed be a race condition. In practice, because of the way the event system works, the behavior could vary wildly (one could read, both could read, neither could read, unrelated events could be removed from the queue). I'm told that in recent versions this behaves in a more consistent manner, but it's certainly against the rules and I wouldn't recommend it.

 

 

As for your code, I don't see anything obvious, but this clearly isn't the complete code and it's not the problematic version.

 

Some relevant comments:

 

  1. Consider keeping the event handling code in this VI. I don't see that you gain anything from moving it to a subVI unless you want to create different VIs with the same functionality. It certainly hurts readability.
  2. You didn't unregister for the events when the loop is over. This can sometimes be an issue. It might be your problem, but I'm guessing not.
  3. Why is the VI non-reentrant? I thought you switched between VIs running in parallel.
  4. At first glance, the code seems too complicated, but I understand that you're refactoring and I didn't analyze it closely. It's possible it could be simplified.

___________________
Try to take over the world!
0 Kudos
Message 19 of 23
(2,139 Views)

@smallmediumlarge wrote:

Yeah now that I think about it, I guess it doesn't fit the definition of "race condition"; I just meant that it can lead to unexpected behavior in your code because you have two 

event structures competing to access the same event queue.


Not even just "unexpected" behavior, but truly, undefined behavior! Anectodally, given one event registration queue filled with N events, and two event structures handling (dequeueing) events -- I think the number of events that could end up being handled is on the range [0, >2N) -- not even within reasonable bounds of expectation.

 

One comment I see in your code: "I disabled this because I register for events in the INIT subVI" -- incidentally, this solves a unique boundary condition problem where many reference designs you'll find in LabVIEW today fail -- catching events that are posted prior to registering. Good job Smiley Happy

 

Keep up the good work innovating, and look back on this code in 1yr, then 2yrs, then 5yrs.

0 Kudos
Message 20 of 23
(2,133 Views)