usb 2.4.1 → 2.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.4.2] - 2022-05-27
4
+
5
+ ### Fixed
6
+ - Fixed multiple events with device detection on Windows - [`512`](https://github.com/node-usb/node-usb/pull/512) ([Alba Mendez](https://github.com/mildsunrise))
7
+
3
8
  ## [2.4.1] - 2022-05-07
4
9
 
5
10
  ### Fixed
package/binding.gyp CHANGED
@@ -19,6 +19,7 @@
19
19
  './src/node_usb.cc',
20
20
  './src/device.cc',
21
21
  './src/transfer.cc',
22
+ './src/thread_name.cc',
22
23
  ],
23
24
  'cflags_cc': [
24
25
  '-std=c++14'
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "usb",
3
3
  "description": "Library to access USB devices",
4
4
  "license": "MIT",
5
- "version": "2.4.1",
5
+ "version": "2.4.2",
6
6
  "main": "dist/index.js",
7
7
  "engines": {
8
8
  "node": ">=10.20.0 <11.x || >=12.17.0 <13.0 || >=14.0.0"
Binary file
Binary file
Binary file
package/src/device.cc CHANGED
@@ -14,7 +14,7 @@ Device::Device(const Napi::CallbackInfo& info) : Napi::ObjectWrap<Device>(info),
14
14
  device = info[0].As<Napi::External<libusb_device>>().Data();
15
15
  libusb_ref_device(device);
16
16
 
17
- std::map<libusb_device*, Device*> byPtr = env.GetInstanceData<ModuleData>()->byPtr;
17
+ std::map<libusb_device*, Device*>& byPtr = env.GetInstanceData<ModuleData>()->byPtr;
18
18
  byPtr[device] = this;
19
19
 
20
20
  DEBUG_LOG("Created device %p", this);
@@ -25,7 +25,7 @@ Device::~Device() {
25
25
  DEBUG_LOG("Freed device %p", this);
26
26
 
27
27
  ModuleData* instanceData = env.GetInstanceData<ModuleData>();
28
- std::map<libusb_device*, Device*> byPtr = instanceData->byPtr;
28
+ std::map<libusb_device*, Device*>& byPtr = instanceData->byPtr;
29
29
 
30
30
  auto it = byPtr.find(device);
31
31
  if (it != byPtr.end() && it->second == this)
@@ -38,7 +38,7 @@ Device::~Device() {
38
38
  // or create a new one and add it to the map.
39
39
  Napi::Object Device::get(Napi::Env env, libusb_device* dev) {
40
40
  ModuleData* instanceData = env.GetInstanceData<ModuleData>();
41
- std::map<libusb_device*, Device*> byPtr = instanceData->byPtr;
41
+ std::map<libusb_device*, Device*>& byPtr = instanceData->byPtr;
42
42
 
43
43
  auto it = byPtr.find(dev);
44
44
  if (it != byPtr.end()) {
package/src/node_usb.cc CHANGED
@@ -1,4 +1,5 @@
1
1
  #include "node_usb.h"
2
+ #include "thread_name.h"
2
3
 
3
4
  Napi::Value SetDebugLevel(const Napi::CallbackInfo& info);
4
5
  Napi::Value UseUsbDkBackend(const Napi::CallbackInfo& info);
@@ -42,6 +43,7 @@ void handleHotplug(HotPlug* info){
42
43
  }
43
44
 
44
45
  void USBThreadFn(ModuleData* instanceData) {
46
+ SetThreadName("node-usb events");
45
47
  libusb_context* usb_context = instanceData->usb_context;
46
48
 
47
49
  while(true) {
@@ -0,0 +1,79 @@
1
+ // Definition of a SetThreadName function with an emphasis in "portability",
2
+ // meaning we prefer cautiously failing over creating build errors (or crashes)
3
+ // on exotic platforms. To do this, we only include/link against very
4
+ // few & widely available symbols.
5
+ #include "thread_name.h"
6
+
7
+ #if defined(__linux__)
8
+
9
+ // For Linux use the prctl API directly. prctl symbol
10
+ // should be available under any libc.
11
+ #include <sys/prctl.h>
12
+
13
+ // Define here to avoid relying on kernel headers being present
14
+ #define PR_SET_NAME 15 /* Set process name */
15
+
16
+ bool SetThreadName(const char* name) {
17
+ return prctl(PR_SET_NAME, name, 0, 0, 0) >= 0;
18
+ }
19
+
20
+ #elif defined(__APPLE__)
21
+
22
+ // For MacOS use the dynamic linker because I don't
23
+ // want to take any risks
24
+ #include <dlfcn.h>
25
+
26
+ extern "C" typedef int (*SetNameFn)(const char*);
27
+
28
+ bool SetThreadName(const char* name) {
29
+ auto pthread_setname_np = reinterpret_cast<SetNameFn>(
30
+ dlsym(RTLD_DEFAULT, "pthread_setname_np"));
31
+ if (pthread_setname_np == nullptr)
32
+ return false;
33
+ return pthread_setname_np(name) == 0;
34
+ }
35
+
36
+ #elif defined(_WIN32)
37
+
38
+ // For Windows, we use the new SetThreadDescription API which
39
+ // is only available in newish versions. To avoid taking any
40
+ // risks (and because on certain versions it's the only
41
+ // option to access the API), we use the dynamic linker
42
+ #include <windows.h>
43
+
44
+ extern "C" typedef HRESULT (WINAPI *SetThreadDescriptionFn)(HANDLE, PCWSTR);
45
+
46
+ static SetThreadDescriptionFn RetrieveSymbol(const char* objectName) {
47
+ auto mod = GetModuleHandleA(objectName);
48
+ if (mod == nullptr) return nullptr;
49
+ auto symbol = GetProcAddress(mod, "SetThreadDescription");
50
+ return reinterpret_cast<SetThreadDescriptionFn>(symbol);
51
+ }
52
+
53
+ #include <locale>
54
+ #include <codecvt>
55
+ #include <string>
56
+
57
+ bool SetThreadName(const char* name) {
58
+ auto SetThreadDescription = RetrieveSymbol("Kernel32.dll");
59
+ // apparently, MSDN is wrong and the symbol is defined in
60
+ // KernelBase.dll, so try that too
61
+ if (SetThreadDescription == nullptr)
62
+ SetThreadDescription = RetrieveSymbol("KernelBase.dll");
63
+
64
+ if (SetThreadDescription == nullptr) return false;
65
+
66
+ std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
67
+ std::wstring wide_name = converter.from_bytes(name);
68
+
69
+ auto result = SetThreadDescription(GetCurrentThread(), wide_name.c_str());
70
+ return SUCCEEDED(result);
71
+ }
72
+
73
+ #else
74
+
75
+ bool SetThreadName(const char* name) {
76
+ return false;
77
+ }
78
+
79
+ #endif
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Sets the name of the calling thread to `name`, which is
3
+ * a NUL terminated UTF-8 string. Returns true if success,
4
+ * false if error or unsupported platform.
5
+ *
6
+ * Since this is an OS-dependent operation, the requirements
7
+ * of `name` may vary depending on platform. For example on
8
+ * Linux, the maximum length (excluding the terminator) is
9
+ * 16 bytes, and UTF-8 isn't strictly required (only conventional).
10
+ */
11
+ bool SetThreadName(const char* name);