nf-debugger
nf-debugger copied to clipboard
Improvements for async device management and exclusive access to device
Description
One feature of the proposed test platform v3 should be in this library:
-
System-wide exclusive access to a device via system-wide mutex, required to avoid competition between e.g.,Device Explorer auto-discovery, test platform etc. If this is used, it is possible for the nanoFramework tools to wait for a device to become available instead of throwing an exception. If an exception is thrown, that is an indication of a real problem, not a competition with other nanoFramework tools. Not sure if that also means the WaitAndRetry in the PortSerialManager should be removed.
-
Use of System-wide exclusive access in the PortSerialManager+DeviceWatcher; async part of that operation moved from PortSerialManager to DeviceWatcher. Also updated PortTcpIpManager+DeviceWatcher.
The other changes have been triggered by the use of the debugger library in test platform v3:
-
Local locks for global NanoFrameworkDevices collection because of discovery of devices is asynchronous (and because of the use of multiple async PortManagers in the test platform v3):
- Make sure all list operations use a lock of the collection
- PortTcpIpManager._networkDevices made static as it acts as a complement to the NanoFrameworkDevices collection - if there are multiple, the device list management does not work properly for a non-static _networkDevices.
-
Serial ports: DeviceWatcher now has a static method to find all serial ports, incl exclusion list, so that all nanoFramework tools can use the same method to find the ports. Also to be used in the test platform v3.
-
Port*Manager returns the added or already registered device for PostBase.AddDevice. Makes use in test platform code easier.
-
Fixed OnDeviceEnumerationCompleted logic if both AddDevice and a device watcher are used. The OnDeviceEnumerationCompleted is now (indirectly) fired by the DeviceWatcher.
-
Also fixed at least one statement that would result in an exception if NanoNetworkDevices have been discovered before NanoSerialDevices.
-
.editorconfig added
Motivation and Context
These changes are a result of the work for test platform v3: improvements and one extra feature that should be in this library rather than in test platform v3. But the changes are probably also relevant for other applications, so they are presented in a separate PR.
In the proposed test platform v3 I've introduced a mechanism that nanoFramework tools can use to get exclusive access to a device. The tool waits for the device to become available (optionally with timeout) rather than throwing an exception. If an exception is thrown, either a non-nanoFramework application is using the device or it is not a nanoFramework tool. This mechanism is needed in the test platform to prevent issues if the developer starts multiple test hosts. But is also prevents interference from the Device Explorer in Visual Studio, if the VS extension would use the same mechanism.
That mechanism should not be part of the test platform, but should be in this library. I'm prepared to ensure that the mechanism is working correctly in nanoff (and of course in the test platform v2 and v3). It should work out of the box for the VS Extension once the submodule reference to the nf-debugger repository has been updated, and would prevent device detection issues if two Visual Studio instances are open and try to discover devices at the same time . That requires this library and NuGet package to be updated first.
The other changes are related to the (ease of) use of the library in the test platform. The library seems to be created for device watcher-type applications, and some code for modifications of the global list of devices are not properly protected against simultaneous updates. Tried to fix that. Also: an application like test platform may create a debugger for a specific device that has not previously been discovered via a device watcher, but the application has to get the result from the global list anyway instead of having the device as a return value of the call.
I've noticed that there is some specialized code to prevent a connection to certain serial devices. Made that code available via a static method, so an application like test platform v3 can use exactly the same code to know which serial ports are present.
How Has This Been Tested?
Using the Serial Test App, at least for the serial devices. Don't know how to connect a device via TCP/IP (is that supposed to work?). The global exclusive access was tested by running one Serial Test App in the debugger and one outside Visual Studio.
Types of changes
- [x] Improvement (non-breaking change that improves a feature, code or algorithm)
- [x] Bug fix (non-breaking change which fixes an issue with code or algorithm)
- [x] New feature (non-breaking change which adds functionality to code)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Config and build (change in the configuration and build system, has no impact on code or features)
- [ ] Dependencies (update dependencies and changes associated, has no impact on code or features)
- [ ] Unit Tests (add new Unit Test(s) or improved existing one(s), has no impact on code or features)
- [ ] Documentation (changes or updates in the documentation, has no impact on code or features)
Checklist:
- [x] My code follows the code style of this project (only if there are changes in source code).
- [ ] My changes require an update to the documentation (there are changes that require the docs website to be updated).
- [ ] I have updated the documentation accordingly (the changes require an update on the docs in this repo).
- [x] I have read the CONTRIBUTING document.
- [x] I have tested everything locally and all new and existing tests passed (only if there are changes in source code).
- [ ] I have added new tests to cover my changes.