Skip to content

Commit 8b0c9e1

Browse files
committed
Don't leak device handle in macOS 10.10 or newer
Merged upstream fix for macOS: libusb/hidapi@cdc473d In one of the early versions of macOS, when you try to close the device with IOHIDDeviceClose() that is being physically disconnected. Starting with some version of macOS, this crash bug was fixed, and starting with macSO 10.15 the opposite effect took place: in some environments crash happens if IOHIDDeviceClose() is _not_ called. This patch is to keep a workaround for old versions of macOS, and don't have a leak in new/tested environments. Fixes #12255 (cherry picked from commit 5925c27)
1 parent 7f74c1e commit 8b0c9e1

File tree

3 files changed

+19
-6
lines changed

3 files changed

+19
-6
lines changed

src/hidapi/configure.ac

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ case $host in
7979
backend="mac"
8080
os="darwin"
8181
threads="pthreads"
82-
LIBS="${LIBS} -framework IOKit -framework CoreFoundation"
82+
LIBS="${LIBS} -framework IOKit -framework CoreFoundation -framework AppKit"
8383
;;
8484
*-freebsd*)
8585
AC_MSG_RESULT([ (FreeBSD back-end)])

src/hidapi/mac/Makefile-manual

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ COBJS=hid.o
1414
CPPOBJS=../hidtest/hidtest.o
1515
OBJS=$(COBJS) $(CPPOBJS)
1616
CFLAGS+=-I../hidapi -Wall -g -c
17-
LIBS=-framework IOKit -framework CoreFoundation
17+
LIBS=-framework IOKit -framework CoreFoundation -framework AppKit
1818

1919

2020
hidtest: $(OBJS)

src/hidapi/mac/hid.c

+17-4
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737

3838
#define VALVE_USB_VID 0x28DE
3939

40+
/* As defined in AppKit.h, but we don't need the entire AppKit for a single constant. */
41+
extern const double NSAppKitVersionNumber;
42+
4043
/* Barrier implementation because Mac OSX doesn't have pthread_barrier.
4144
It also doesn't have clock_gettime(). So much for POSIX and SUSv2.
4245
This implementation came from Brent Priddy and was posted on
@@ -131,6 +134,7 @@ struct hid_device_list_node
131134
};
132135

133136
static IOHIDManagerRef hid_mgr = 0x0;
137+
static int is_macos_10_10_or_greater = 0;
134138
static struct hid_device_list_node *device_list = 0x0;
135139

136140
static hid_device *new_hid_device(void)
@@ -485,6 +489,7 @@ static int init_hid_manager(void)
485489
int HID_API_EXPORT hid_init(void)
486490
{
487491
if (!hid_mgr) {
492+
is_macos_10_10_or_greater = (NSAppKitVersionNumber >= 1343); /* NSAppKitVersionNumber10_10 */
488493
return init_hid_manager();
489494
}
490495

@@ -1138,8 +1143,10 @@ void HID_API_EXPORT hid_close(hid_device *dev)
11381143
if (!dev)
11391144
return;
11401145

1141-
/* Disconnect the report callback before close. */
1142-
if (!dev->disconnected) {
1146+
/* Disconnect the report callback before close.
1147+
See comment below.
1148+
*/
1149+
if (is_macos_10_10_or_greater || !dev->disconnected) {
11431150
IOHIDDeviceRegisterInputReportCallback(
11441151
dev->device_handle, dev->input_report_buf, dev->max_input_report_len,
11451152
NULL, dev);
@@ -1162,8 +1169,14 @@ void HID_API_EXPORT hid_close(hid_device *dev)
11621169

11631170
/* Close the OS handle to the device, but only if it's not
11641171
been unplugged. If it's been unplugged, then calling
1165-
IOHIDDeviceClose() will crash. */
1166-
if (!dev->disconnected) {
1172+
IOHIDDeviceClose() will crash.
1173+
1174+
UPD: The crash part was true in/until some version of macOS.
1175+
Starting with macOS 10.15, there is an opposite effect in some environments:
1176+
crash happenes if IOHIDDeviceClose() is not called.
1177+
Not leaking a resource in all tested environments.
1178+
*/
1179+
if (is_macos_10_10_or_greater || !dev->disconnected) {
11671180
IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeNone);
11681181
}
11691182

0 commit comments

Comments
 (0)