I'm having a go at implementing some of the Windows Sockets API and run into the same issue Rolf talks about in this post:
Quote
Just one more comment. The error handling with WSAGetLastError() is probably never gonna return a meaningful error. (WSA)GetLastError() retrieves a thread local storage value set previously by another function. That assumes that the previous function and GetLastError() are called in the same thread and without any other function in between that could set that value. Since the CLN's are set to execute in any thread this is absolutely impossible to guarantee and in my experience actually almost never happens either.
Not even setting both CLNs to execute in the UI execution system would be able to guarantee proper operation, since theoretically there could still execute another call to an API that influences this value, between when LabVIEW calls the recv() function and when it eventually calls the WSAGetLastError().
My issue is a little more fine-grained, perhaps. If I have my two CLNs SomeWSACall() and WSAGetLastError() on the same block diagram, happy days - I get my socket error code. However, I wrapped that WSAGetLastError() call into a subVI and now it doesn't work! Evidently, using a subVI ensures that something, somewhere makes a call to WSASetLastError() in the UI thread. I did open a support issue with NI about it, but I expect they'll tell me what I already know.
Why is it that we do not get the fine-grained thread control for CLNs as we do for VIs - or is it that "execution systems" in LabVIEW are not explicitly threads?
Though I'm referring to specific functions, this is really more broad - I will probably be working with several other Windows APIs in the future and it would be helpful to have a complete grasp of the nuances here.