LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Why does this extra REG EVENTS cause memory leak?


CoastalMaineBird wrote: 

18633iF0CA7B8066B66908

 


Unrelated to the original topic, there's a leak of encapsulation that leads to a subtle race condition here -- but don't feel bad! Many reference designs today do this. Smiley Sad

 

By registering for events outside of where the User Event Ref could be mutexed, a call to "Get User Event Refs" followed by "Register for Events" on the calling diagram could miss "Post User Event" sent between those two invocations.

 

Consider on the diagram above, placing a function called "Update Display" to print out "Connecting..." on the "RTEC Display Update" channel onto the error wire after "RTEC Rcvr Controller" but before "HDT Log Mgr."

 

Sure, it's possible to eliminate the race condition by knowing a lot about the application ... but that won't scale for team size and application size (if scalability is important).

 

One way to fix this issue is to keep the User Event encapsulated, yet pass out the Event Registration Refnum which was created within the object.

0 Kudos
Message 11 of 18
(960 Views)

 the original behavior of a leak generated by unhandled events is correct and expected.

 

 

So, is it then improper to register a cluster of 30 event refnums en masse, if I only have a handler for a few of them?

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 12 of 18
(950 Views)

As long as your registration wire is ran to an event handler, you are OK.

The event structure is smart enough to discard unhandled events and won't leak.

 

The leak occurs when you register for an event and then fail to wire that registration wire to an event handler.

0 Kudos
Message 13 of 18
(941 Views)

By registering for events outside of where the User Event Ref could be mutexed, a call to "Get User Event Refs" followed by "Register for Events" on the calling diagram could miss "Post User Event" sent between those two invocations.

 

OK, you're over my head here, but I'd like to understand what you mean.

 

Specifically, I don't know what point you mean by "where the User Event Ref could be mutexed".  What point on the diagram does that refer to?

 

I do see a race condition between two calls to the HDT LOG Manager.  I understand that, and don't care in this instance.

 

When you say "Consider... placing a function", are you suggesting that would CURE the race condition, or that it would SHOW it?

 

One way to fix this issue is to keep the User Event encapsulated, yet pass out the Event Registration Refnum which was created within the object.

 

But I need to have several Registrations for several event loops and I don't know who is going to be open at any given time.

So I have the object (RECVR CONTROLLER) Generate the EVENT refnums and keep them, then each window registers for the ones it wants to use.

 

Is there a better pattern? (I haven't digested your "Sundry" material yet, perhaps it's in there).

 

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 14 of 18
(930 Views)

The event structure is smart enough to discard unhandled events and won't leak.

 


That seems to contradict what Jack said:

 

 the original behavior of a leak generated by unhandled events is correct and expected.

 

 

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 15 of 18
(915 Views)

I believe the confusion here is between unhandled events and unwired but registered events. I think that our language is getting crossed.

 

I'm using 'unhandled to' mean an event has been registered for and wired to an event structure but the event structure doesn't have a case to handle it.

 

I'm referring to the other case as 'registered but unwired' (ie. the registered event that Jack circled in yellow)

 

What I've seen experimentally is that a registered, wired but unhandled (no specific case to handle it in the event structure) events will not leak memory. It appears that the even structure manages these unhandled events.

Jack, correct me if I'm wrong.

0 Kudos
Message 16 of 18
(907 Views)

I agree that Jack's presentation is highly recommended, because it covers many important points. It's not all-encompassing, but its SNR is much higher than the NIWeek presentations we often see (which is why I keep linking to it. Good job, Jack). 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).

 

 


@CoastalMaineBird wrote:

Specifically, I don't know what point you mean by "where the User Event Ref could be mutexed".  What point on the diagram does that refer to?


Jack means that you have a potential race condition - an event (or multiple) could be generated before you registered to receive events, and so that event will not be processed by the event structure.

 

His "consider" is a theoretical example. Another potential one in your example - if the HDT Log Mgr VI can fire the RTEC Error event, the bottom call could fire the event before the register node runs.

 

Jack's saying that one simple way of avoiding this is to register in the same VI which creates the user event and that VI is the mutex - since the VI has to finish running before the reference is returned, the registration is guaranteed to happen before any events are generated.

 

Note that this also has its disadvantages - it doesn't guarantee you will handle the registered events (so they can leak), it's a problem if you want to send the same event to multiple listeners, changing the event registration can be a pain, because it doesn't auto-update and you have to replace and relink the indicator in the connector pane, etc. Like many things in life, it's a tradeoff.


___________________
Try to take over the world!
0 Kudos
Message 17 of 18
(846 Views)

an event (or multiple) could be generated before you registered to receive events, and so that event will not be processed by the event structure.

 

 

That cannot happen in this case, although you can't tell that from this section of code.

The events come from a TCP datastream from a PXI box.

Since I just connected, there is no stream until I request one (not shown on this code, but it's AFTER the registration).

 

I have fallen into that pothole in the past, though.

 

The RCVR CONTROLLER generates the events the first time it is called. After that, it simply returns the cluster that it generated the first time.

 

There are several places I need to register those same events.  I can't generate them every time - the RCVR needs ONE event to send when message X comes in.  So I have to have ONE place that generates them.

 


All of this is beside the main point. Which is that registering for events and ignoring the registration is a memory leak. In this case the DATA event happens at 10 Hz, and the DISPLAY event happens at 2 Hz so there are 12 events per second.  Overnight, that adds up to significant RAM wastage.

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 18 of 18
(801 Views)