LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

DeclareThreadSafeVar() and what it does if it fails (documentation request)

Solved!
Go to solution

The LabWindows/CVI 2017 code I maintain uses thread safe variables, defined like this:

// Thread safe variables.
DeclareThreadSafeVar (TCP_MESSAGE_DATA, LabViewTCP_MessageData);

This then uses the GetPointerTo thing to lock/access it, and ReleasePointerTo to unlock it. I am looking for some documentation on this.

 

I just searched the online manual for DeclareThreadSafeVar() and it does not show up for me in the results:

 

https://www.ni.com/docs/en-US/search?bundle=labwindows-cvi&q=DeclareThreadSafeVar

 

I did find DefineThreadSafeScalarVar(), but that is not what I am working on.

 

What can cause this call to fail or return an invalid pointer? Does it return NULL like you would get from something like malloc()? And if it returns an invalid pointer, do you still have to ReleasePointerTo afterwards?

 

Thanks for any "pointers" on this subject 😉

0 Kudos
Message 1 of 4
(163 Views)
Solution
Accepted by topic author AllenInIowa

DeclareThreadSafeVar is a macro that actually evaluates to DeclareThreadSafeScalarVar macro, so the documentation for that macro gives you a lot of to help understanding how to use it. All documentation lies in the help for the utility library and macro definitions can be found in utility.h include file.

This is one of the help topics about thread safe variables: Programming with DefineThreadSafeScalarVar 

 

By digging into the macros, you'll find that TSV definition ultimately calls CmtNewTSV () function which returns 0 on success or negative error values on error; similarly, GetPointerTo macro calls  CmtGetTSVPtr () function which again returns a negative value on error.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 2 of 4
(127 Views)

@RobertoBozzolo wrote:

DeclareThreadSafeVar is a macro that actually evaluates to DeclareThreadSafeScalarVar macro, so the documentation for that macro gives you a lot of to help understanding how to use it. All documentation lies in the help for the utility library and macro definitions can be found in utility.h include file.

This is one of the help topics about thread safe variables: Programming with DefineThreadSafeScalarVar 

 

By digging into the macros, you'll find that TSV definition ultimately calls CmtNewTSV () function which returns 0 on success or negative error values on error; similarly, GetPointerTo macro calls  CmtGetTSVPtr () function which again returns a negative value on error.


Thank you. Most helpful.

 

The root problem is seeing runtime exceptions that say invalid handle. Perhaps my checks should be for -1 instead of NULL. I will check out utility.h and do some learning.

0 Kudos
Message 3 of 4
(86 Views)

@RobertoBozzolo wrote:

By digging into the macros, you'll find that TSV definition ultimately calls CmtNewTSV () function which returns 0 on success or negative error values on error; similarly, GetPointerTo macro calls  CmtGetTSVPtr () function which again returns a negative value on error.


This makes so much more sense now. Thank you.

 

datatype *GetPointerTo ## name(void)                                    \
{                                                                       \
    void *_locked ## name ## Ptr = NULL;                                \
    CmtGetTSVPtr (_locked ## name, &_locked ## name ## Ptr);            \
    CheckThreadSafeVarNestedLockCount(datatype, name, maxGetPointerNesting);\
    return (datatype *)_locked ## name ## Ptr;                          \
}   

Unfortunately, the macro does not do any error checking. I need to make a test to see if the passed-in pointer is just left alone. If so, perhaps making sure it is pre-initialized to NULL would be enough.

SomeStruct *ptr = NULL;

ptr = GetPointerToSomeStructData();

if (NULL == ptr)
{
    // It did not work. Did it?
}

If that works, that is an easy band-aide to put in our code. The root cause is still not understanding/properly implementing how the thread variables are being created/destroyed in the program.

 

0 Kudos
Message 4 of 4
(82 Views)