Jump to content

JasonC

NI
  • Posts

    9
  • Joined

  • Last visited

Posts posted by JasonC

  1. It seems to say that opening a VI ref then closing it immediately before attempting to re-open by name (whilst linked via the error cluster) will cause a race condition. This should not be the case. The second call (by name) should always return an error in this example. If it doesn't, then it is violating dataflow since the ref should be at least marked as invalid if not completely removed from memory and, as there are no other open references, the second call should fail.

     

    ShaunR, I'm slightly confused by your most recent post. I'm assuming the third quote attributed to me was actually your comment. I'm responding to that.

     

    It may surpise you, but yes, there is a potential race condition there. Assuming the reference is the only thing holding the target VI in memory, the second call (by name) might return an error but it also might succeed.

     

    Several LV releases ago, the Close Reference function was always asynchronous making it very common for the target VI to briefly remain in memory after the close. Somewhere around LV 8.2, I made a change that made the Close Reference synchronous much of the time. The keyword here is much. There are a variety of things that can determine whether or not the Close Reference will immediately.

     

    So, if the Close Reference determines it cannot immediately dispose of the target VI, the referenced code is a race condition.

    To improve my own understanding, what is one way to obtain a reference to a control in a local VI (not accessed remotely through VI server) that returns a valid value other than the "this" reference?

     

    The most obvious way is via the Open VI Object Reference node. If you call this several times targeting the same object, you will get a different reference each time.

     

    There is not a great way to know you are getting a new reference each time because the comparison primitives compare the target, the reference. If you really want to verify you are getting different references, typecast each reference to an int32. Viewing it has hex makes it a little more human readable.

     

    Most property/invoke nodes that return object references return the "this" reference. However, not all of them do. It is safest to go ahead and close the refs.

  2. It wasn't immediately obvious to me that this applies to all parent references, not just to the (fairly obvious) case that the parent is a VI. To extend the example given, if you open a vi reference, get a reference to the panel, get a reference to the controls, close the panel reference, but leave the vi reference open, then the control references are invalidated.

     

    This does not extend to all reference types. It only applies to the parent reference being a VI. In your example, closing a panel reference will not invalidate references obtained from the panel reference.

    In the previous example, closing the VI reference immediately before or in parallel to the second Open VI Reference function creates a race condition

     

    Surely this is a "bug" that violates dataflow.

     

    The image with two Open VI Ref calls does not violate dateflow. Unless I am missing something, the diagram is syntactically valid. If you believe there is a bug, will you elaborate?

    ned said:

    There's nothing special about the refs obtained from the Controls[] property that makes them different than a regular control reference.  Each control has a unique refnum which will be returned whenever that control is referenced, regardless of how that refnum is obtained (direct reference, controls[] property, etc).  As a result, no need to close those references. 

     

    This is not true. There are plenty of times you should close control references. That is one of the points of this document.

     

    It is true that each control has a unique refnum. (At NI, we call it the "this" reference.) And it is true that that refnum is often returned by implicit references, properties, etc. Closing the "this" reference is a no-op so you can technically get a way without closing it.

     

    However, there are numerous ways to obtain control references and not all of them return the "this" reference. There is not a good way to know if the reference you obtained is a "this" refernece (other than the few cases stated in the document) so it is best to just go ahead and close the reference.

  3. With SACBR, if you close the reference, it has no effect on the running VI.

    One more thing...if you close the reference, the VI run by an async CBR or a normal CBR will leave memory when the execution completes (assuming there was nothing else keeping the VI in memory).

  4. I assume the caller should close the VI RefNum after calling Start so that the launched VI doesn't stay open. Yes?

    Yes, the user should close the refnum when they are done with it. The reference is not necessary to let the target VI run to completion, so, unless the reference is actually needed later, it should be closed.

  5. If I want the VI to run and dispose of it's own reference, how do I tell it to do that (I will not be calling the wait node since my VI returns its data via a queue).

    When you open the VI reference, the 0x80 and 0x100 options specify different lifetimes for the target VI:

    • 0x80 -- Target VI lifetime independendent of the calling VI.
      ie: Closing the reference will not abort the target VI. The target VI will stay in memory until it finishes.
    • 0x100 -- Target VI lifetime dependent on the calling VI.
      ie: Closing the reference will abort the target VI. If the calling VI runs to completion, the target VI reference will automatically be closed and the target VI will abort.

  6. Now please correct me if I'm wrong, since 0x40 option will always return a refnum to the target (not a clone), if we need to obtain refnums to specific reentrant clones when using the 0x80 or 0x100 options, the only way to do so is to have the clone return a refnum of itself to the caller after it has been started (via a notfier or something).

    Correct. Hopefully, you will not actually need to do this. I hope that the target VI itself could do whatever work needs to be done with the reference (like show the FP).

    But if you really need a reference to the actual clone, the target VI needs to pass it back to the calling VI in someway.

    On a similar note, if you need to match a Start node with a Wait node, you have two options:

    1) Open a VI reference for each pair of Start/Wait nodes

    2) Return something from the target VI that can be used to match a Start and Wait. ex: Passing a unique integer (like a loop index) into and out of the target VI

    The 0x8 option seems to work, but we "should not" use it?

    I'm suprised this works. I would have expected the 0x8 to have no affect.

    • If Start Asynchronous Call is called before Insert VI we instead seem to observe the behavior of the target (not the clone).

    I attached a new version of your sub panel VI that waits before writing to the string indicator. In this example, the sub panel says the target VI ran (after a second) no matter what you set the order of execution to be.

    In your original code, the front panel of the sub panel VI is not loaded until you insert the ref. Since the FP is not loaded, writing to an indicator during execution does not actually update the visible string on the FP. Then, when the FP is loaded, the string indicator gets the default data and not the data from the last time the indicator was written to.

    Sub Panel.vi

  7. You should not use option 0x8 with option 0x80 or 0x100. Or, more generally, you should not use option 0x8 anytime you are opening a strict VI reference. When opening a strict VI reference, a reentrant instance is returned automatically so 0x8 is pointless (and harmless). The 0x8 option is really only useful when used in conjunction with the Run VI method.

    There were two problems with the original Main.vi from mje.

    Issue 1:

    Option 0x40 was passed in. This option works for both the Async CBR and the normal CBR in a similar way. Passing 0x40 makes the reference returned be to the actual target VI and not a clone of the target VI. Then, when you perform a CBR or a Start Async Call, you actually call a clone. This can cause issues when doing things like showing a FP or embedding it into a subVI. The called VI is not the same as the VI reference.

    When opeing a VI reference, if you do not pass in option 0x40 and you are opening a strict reference and the target VI is reentrant, the reference returned will be to a clone VI. This works the same whether or not 0x100 is passed in.

    Issue 2:

    The Start Async Call happend before inserting the VI reference into the sub panel. In this case, the asynchronously run VI runs to completion before being inserted into the sub panel. Inserting the sub panel then loads the FP of the target VI. Since the VI already ran, we end up with the default data and we end up seeing a message saying the VI had not run.

    So, if you insert into the sub panel first, the FP will be loaded. Then, when you start an async call, the results will be remembered by the FP.

    I attached a new version of Main.vi that works.

    More Info on Option 0x40:

    Option 0x40 allows multiple synchronous calls with one reference.

    ie: You open one reference to a reentrant VI with option 0x40. You then branch the wire and wire it to two CBR nodes. Each CBR node can execute a different reentrant instance of the target VI at the same time. If 0x40 was not passed, one CBR would run while the other blocked until it finished.

    It works the same for the Async CBR other than the fact on the "Wait On Async Call" works. The Wait will return one of the calls that finished for that VI reference, but you do not necessarily know which one.

    I attached "Reentrant.vi" and "Option0x40.vi" to demonstrate option 0x40.

    Main.vi

    Reentrant.vi

    Option0x40.vi

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.