Closed diablodale closed 1 year ago
Apple's compiler appears to not match the behavior of all the others and is failing on use of std::pair in constexpr.
AppleClang 14.0.0.14000029
-- The CXX compiler identification is AppleClang 14.0.0.14000029
.....
/Users/runner/work/XLink/XLink/src/pc/protocols/usb_host.cpp:104:71: error: constexpr variable 'VID_PID_TO_DEVICE_STATE' must be initialized by a constant expression
static constexpr std::array<std::pair<VidPid, XLinkDeviceState_t>, 4> VID_PID_TO_DEVICE_STATE = {{
^ ~~
/Users/runner/work/XLink/XLink/src/pc/protocols/usb_host.cpp:105:5: note: non-constexpr constructor 'pair<true, false>' cannot be used in a constant expression
{{0x03E7, 0x2485}, X_LINK_UNBOOTED},
^
/Applications/Xcode_14.2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__utility/pair.h:171:5: note: declared here
pair(_T1 const& __t1, _T2 const& __t2)
^
I successfully compile with Clang 14.0.0 on my linux machine. As the internet writes, Apple's compiler is non-standard and quirky 🍏🪱. If anyone on the Luxonis team has access to a Mac, it would be great to have assist on that error. I suspect it is that Apple disabled or broke something with std::pair and constexpr. As a fallback, I can change the vidpid lookup to instead use a simple 3 column array.
This is a large codebase change for which we lack both the extensive testing to be sure to pull it in as well as it requires redoing the mental model of current state. Seems like "libusb++" impl, which might be better suited as a standalone library.
For "just" the sake of #59 I'd rather see a more "non intrusive" function level try/catch.
Any improvements/fixes part of this PR that address some other specific problems, would be neat to be addressed by a separate PR.
Sorry for the delay on the feedback, but was headdown this week
Hi, no worries. We spoke about this before -- that when our goals don't align we can do different things. And that's ok 🙂👍 We also spoke before about your group's testing methodology/group so I have some insight there too. Happy to discuss anytime here or offline. 🕊️✌️
As I first approach the crashing bugs with a try/catch around every function, it lead to several discoveries that changed my approach. Please do not take these as insults. Instead, I'm sharing with you my thought process and just describing what I saw in the USB code. The PoE code of Xlink I have not investigated.
These led me to the need for a simple c++ wrapper around the subset of libusb used by xlink. While it could be a separate project, I have no desire or need to do that work. It would require much more work to handle all the libusb functions, structs, async io, etc.
When I had the first few wrappers of resources like device_list
or usb_device
, it was simply inserting it where the C-call already was and then try/catching the wrapper's errors. But doing that very quickly simplified code where a chain of if/thiserror/thaterror/defaulterror
is no longer needed and the "close/release" of the resource is automatic. Hundreds of lines of usb_host.cpp
code was then unneeded. Then with resources (this is primarily about resources) that release themselves with RAII, I could then start to do the try/catch work that removed yet more (sometime incorrect) error handling of those resources.
Which got the PR to this current state. I understand you telling me your testing resources are elsewhere. And that's ok. 🙂👍
For now, I'm going to continue with my fork of xlink as I already feel more confident with its handling of USB (in particular error conditions). The new code is not ready yet, but already it resolves the issues I write above. Reliability with no fails/crashing for up to a week is important for my use cases so my priorities are oriented in that direction.
If there isn't any further life for this PR, I can close it and continue work in my fork.
I have one ask. The mac-only compiler fail with constexpr ?might? have a workaround. I'd like to force-push a commit over itself several times trying different alternatives into this PR to test each approach. Any concerns with that?
For now, I'm going to continue with my fork of xlink as I already feel more confident with its handling of USB (in particular error conditions). The new code is not ready yet, but already it resolves the issues I write above. Reliability with no fails/crashing for up to a week is important for my use cases so my priorities are oriented in that direction.
If there isn't any further life for this PR, I can close it and continue work in my fork.
I agree with your rundown - I would love to see this go further, but it also has to address a (big enough) pain point to warrant indepth review and manual testing (as XLink doesn't have a USB centric testing - TCPIP might be simpler to cover in this regards - develop_server
). That said, I'd gladly keep up with developments here and further see what other issues it resolves, and re-review if/when the issue presses/becomes a pain point in our mainline.
I have one ask. The mac-only compiler fail with constexpr ?might? have a workaround. I'd like to force-push a commit over itself several times trying different alternatives into this PR to test each approach. Any concerns with that?
Not an issue at all
Otherwise on the questions:
can we shift XLink to be a C++14 project? the cmake's in XLink are still set to c++11. If no, then I'll need to change some code.
IMO yes - underlying DepthAI is already at C++14, and it being the main consumer, it aligns nicely
Code comments in refLibusbDeviceByName() say it filters by Myraid devices. It actually doesn't. This can be added if needed.
I don't think this has to be changed unless code relies on it - so I'd just modify the comment instead. (was likely a culprit of a refactor to begin with)
I've pushed the last commit to this branch. It includes markdown and mermaid documentation for usage and object model for the libusb wrapper. Its really quite simple. 🔢 This wrapper replaces much of the old Xlink C-style code for its usb transport.
Moving forward, fixes from this PR and more will usually be in my fork at https://github.com/diablodale/XLink/ Closing.
Adds c++ wrappers for the minimum set of features needed without introducing major Xlink code refactoring. fixes #59 I can't move much further until the questions below are answered.
dai::libusb
namespaceusb_error
for exceptionsusb_context
,usb_device
,device_list
,device_handle
,config_descriptor
device_handle::claim_interface()
,device_handle::set_configuration()
, etc. to manage interfaces and fix resource leak bugs I foundlibusb_get_device_list()
Questions
mvLog
entries. Should that be in the wrapper? Or should the Caller do it withcatch() { mvLog("had an error: " + myexception.what()); }
. Pros and Cons for both. This is more a style and feature choice.~ The wrapper classes do the logging as it matched the majority of use cases.extern C
fromrefLibusbDeviceByName()
? I don't see a need for it. Does the device firmware code need it?~ I removed it.refLibusbDeviceByName()
say it filters by Myraid devices. It actually doesn't. This can be added if needed.