usb 1.7.2 → 1.8.0-libusb.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/.gitmodules +1 -1
- package/Readme.md +2 -2
- package/binding.gyp +2 -2
- package/libusb/.private/pre-commit.sh +7 -1
- package/libusb/.travis.yml +49 -0
- package/libusb/AUTHORS +44 -3
- package/libusb/Brewfile +4 -0
- package/libusb/ChangeLog +74 -2
- package/libusb/README.md +32 -0
- package/libusb/TODO +1 -1
- package/libusb/Xcode/common.xcconfig +12 -0
- package/libusb/Xcode/config.h +25 -0
- package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +959 -1
- package/libusb/android/README +4 -2
- package/libusb/android/config.h +75 -0
- package/libusb/appveyor.yml +41 -0
- package/libusb/appveyor_cygwin.bat +11 -0
- package/libusb/appveyor_minGW.bat +19 -0
- package/libusb/autogen.sh +1 -1
- package/libusb/bootstrap.sh +3 -16
- package/libusb/configure.ac +108 -80
- package/libusb/doc/doxygen.cfg.in +1785 -739
- package/libusb/examples/Makefile.am +1 -1
- package/libusb/examples/dpfp.c +3 -1
- package/libusb/examples/dpfp_threaded.c +23 -10
- package/libusb/examples/ezusb.c +3 -3
- package/libusb/examples/ezusb.h +2 -2
- package/libusb/examples/fxload.c +31 -9
- package/libusb/examples/hotplugtest.c +35 -7
- package/libusb/examples/listdevs.c +3 -1
- package/libusb/examples/sam3u_benchmark.c +3 -3
- package/libusb/examples/testlibusb.c +277 -0
- package/libusb/examples/xusb.c +40 -34
- package/libusb/libusb/Makefile.am +49 -23
- package/libusb/libusb/core.c +855 -457
- package/libusb/libusb/descriptor.c +72 -78
- package/libusb/libusb/hotplug.c +122 -76
- package/libusb/libusb/hotplug.h +42 -25
- package/libusb/libusb/io.c +625 -390
- package/libusb/libusb/libusb-1.0.def +12 -0
- package/libusb/libusb/libusb.h +218 -150
- package/libusb/libusb/libusbi.h +346 -176
- package/libusb/libusb/os/darwin_usb.c +604 -319
- package/libusb/libusb/os/darwin_usb.h +61 -20
- package/libusb/libusb/os/haiku_pollfs.cpp +367 -0
- package/libusb/libusb/os/haiku_usb.h +113 -0
- package/libusb/libusb/os/haiku_usb_backend.cpp +533 -0
- package/libusb/libusb/os/haiku_usb_raw.cpp +267 -0
- package/libusb/libusb/os/haiku_usb_raw.h +188 -0
- package/libusb/libusb/os/linux_netlink.c +186 -146
- package/libusb/libusb/os/linux_udev.c +36 -14
- package/libusb/libusb/os/linux_usbfs.c +426 -225
- package/libusb/libusb/os/linux_usbfs.h +5 -3
- package/libusb/libusb/os/netbsd_usb.c +21 -77
- package/libusb/libusb/os/openbsd_usb.c +32 -115
- package/libusb/libusb/os/poll_posix.c +38 -5
- package/libusb/libusb/os/poll_posix.h +3 -0
- package/libusb/libusb/os/poll_windows.c +277 -626
- package/libusb/libusb/os/poll_windows.h +11 -44
- package/libusb/libusb/os/sunos_usb.c +1695 -0
- package/libusb/libusb/os/sunos_usb.h +80 -0
- package/libusb/libusb/os/threads_posix.c +24 -26
- package/libusb/libusb/os/threads_posix.h +73 -21
- package/libusb/libusb/os/threads_windows.c +71 -157
- package/libusb/libusb/os/threads_windows.h +68 -44
- package/libusb/libusb/os/wince_usb.c +276 -420
- package/libusb/libusb/os/wince_usb.h +23 -28
- package/libusb/libusb/os/windows_common.h +78 -58
- package/libusb/libusb/os/windows_nt_common.c +1010 -0
- package/libusb/libusb/os/windows_nt_common.h +110 -0
- package/libusb/libusb/os/windows_nt_shared_types.h +147 -0
- package/libusb/libusb/os/windows_usbdk.c +830 -0
- package/libusb/libusb/os/windows_usbdk.h +103 -0
- package/libusb/libusb/os/windows_winusb.c +4391 -0
- package/libusb/libusb/os/windows_winusb.h +783 -0
- package/libusb/libusb/strerror.c +41 -7
- package/libusb/libusb/sync.c +41 -13
- package/libusb/libusb/version.h +1 -1
- package/libusb/libusb/version_nano.h +1 -1
- package/libusb/libusb-1.0.pc.in +1 -1
- package/libusb/msvc/appveyor.bat +27 -0
- package/libusb/msvc/config.h +5 -4
- package/libusb/msvc/ddk_build.cmd +87 -43
- package/libusb/msvc/fxload_2010.vcxproj +24 -104
- package/libusb/msvc/fxload_2012.vcxproj +24 -107
- package/libusb/msvc/fxload_2013.vcxproj +24 -107
- package/libusb/msvc/fxload_2015.vcxproj +91 -0
- package/libusb/msvc/fxload_2017.vcxproj +114 -0
- package/libusb/msvc/fxload_sources +1 -1
- package/libusb/msvc/getopt_2010.vcxproj +16 -75
- package/libusb/msvc/getopt_2012.vcxproj +16 -79
- package/libusb/msvc/getopt_2013.vcxproj +16 -79
- package/libusb/msvc/getopt_2015.vcxproj +73 -0
- package/libusb/msvc/getopt_2017.vcxproj +98 -0
- package/libusb/msvc/getopt_sources +6 -2
- package/libusb/msvc/hotplugtest_2010.vcxproj +18 -99
- package/libusb/msvc/hotplugtest_2012.vcxproj +18 -102
- package/libusb/msvc/hotplugtest_2013.vcxproj +18 -102
- package/libusb/msvc/hotplugtest_2015.vcxproj +83 -0
- package/libusb/msvc/hotplugtest_2017.vcxproj +106 -0
- package/libusb/msvc/hotplugtest_sources +1 -1
- package/libusb/msvc/libusb_2005.sln +20 -20
- package/libusb/msvc/libusb_2010.sln +57 -46
- package/libusb/msvc/libusb_2012.sln +57 -46
- package/libusb/msvc/libusb_2013.sln +57 -50
- package/libusb/msvc/libusb_2015.sln +59 -52
- package/libusb/msvc/libusb_2017.sln +186 -0
- package/libusb/msvc/libusb_dll.dsp +2 -2
- package/libusb/msvc/libusb_dll_2005.vcproj +30 -2
- package/libusb/msvc/libusb_dll_2010.vcxproj +26 -90
- package/libusb/msvc/libusb_dll_2012.vcxproj +28 -96
- package/libusb/msvc/libusb_dll_2013.vcxproj +28 -96
- package/libusb/msvc/libusb_dll_2015.vcxproj +107 -0
- package/libusb/msvc/libusb_dll_2017.vcxproj +134 -0
- package/libusb/msvc/libusb_dll_wince.vcproj +9 -1
- package/libusb/msvc/libusb_sources +10 -5
- package/libusb/msvc/libusb_static.dsp +2 -2
- package/libusb/msvc/libusb_static_2005.vcproj +32 -4
- package/libusb/msvc/libusb_static_2010.vcxproj +24 -83
- package/libusb/msvc/libusb_static_2012.vcxproj +25 -87
- package/libusb/msvc/libusb_static_2013.vcxproj +25 -87
- package/libusb/msvc/libusb_static_2015.vcxproj +98 -0
- package/libusb/msvc/libusb_static_2017.vcxproj +117 -0
- package/libusb/msvc/libusb_static_wince.vcproj +20 -26
- package/libusb/msvc/libusb_wince.sln +88 -88
- package/libusb/msvc/listdevs_2010.vcxproj +16 -99
- package/libusb/msvc/listdevs_2012.vcxproj +16 -102
- package/libusb/msvc/listdevs_2013.vcxproj +16 -102
- package/libusb/msvc/listdevs_2015.vcxproj +83 -0
- package/libusb/msvc/listdevs_2017.vcxproj +106 -0
- package/libusb/msvc/listdevs_sources +2 -1
- package/libusb/msvc/stress_2010.vcxproj +20 -101
- package/libusb/msvc/stress_2012.vcxproj +20 -104
- package/libusb/msvc/stress_2013.vcxproj +20 -104
- package/libusb/msvc/stress_2015.vcxproj +87 -0
- package/libusb/msvc/stress_2017.vcxproj +110 -0
- package/libusb/msvc/stress_sources +21 -0
- package/libusb/msvc/testlibusb_2010.vcxproj +82 -0
- package/libusb/msvc/testlibusb_2012.vcxproj +83 -0
- package/libusb/msvc/testlibusb_2013.vcxproj +83 -0
- package/libusb/msvc/testlibusb_2015.vcxproj +83 -0
- package/libusb/msvc/testlibusb_2017.vcxproj +106 -0
- package/libusb/msvc/testlibusb_sources +20 -0
- package/libusb/msvc/xusb_2010.vcxproj +17 -98
- package/libusb/msvc/xusb_2012.vcxproj +17 -101
- package/libusb/msvc/xusb_2013.vcxproj +17 -101
- package/libusb/msvc/xusb_2015.vcxproj +83 -0
- package/libusb/msvc/xusb_2017.vcxproj +106 -0
- package/libusb/msvc/xusb_sources +1 -1
- package/libusb/tests/stress.c +2 -2
- package/libusb/tests/testlib.c +0 -4
- package/libusb/travis-autogen.sh +39 -0
- package/libusb.gypi +13 -2
- package/package.json +20 -11
- package/prebuilds/android-arm/node.napi.armv7.node +0 -0
- package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
- package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/linux-ia32/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
- package/prebuilds/linux-x64/node.napi.musl.node +0 -0
- package/prebuilds/win32-ia32/node.napi.node +0 -0
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/src/device.cc +1 -1
- package/usb.js +1 -1
- package/.github/workflows/prebuild.yml +0 -49
- package/libusb/INSTALL +0 -234
- package/libusb/README +0 -28
- package/libusb/libusb/os/windows_usb.c +0 -5347
- package/libusb/libusb/os/windows_usb.h +0 -971
- package/libusb/msvc/fxload_2010.vcxproj.filters +0 -25
- package/libusb/msvc/fxload_2012.vcxproj.filters +0 -25
- package/libusb/msvc/getopt_2010.vcxproj.filters +0 -26
- package/libusb/msvc/getopt_2012.vcxproj.filters +0 -26
- package/libusb/msvc/hotplugtest_2010.vcxproj.filters +0 -14
- package/libusb/msvc/hotplugtest_2012.vcxproj.filters +0 -14
- package/libusb/msvc/libusb_dll_2010.vcxproj.filters +0 -81
- package/libusb/msvc/libusb_dll_2012.vcxproj.filters +0 -84
- package/libusb/msvc/libusb_static_2010.vcxproj.filters +0 -74
- package/libusb/msvc/libusb_static_2012.vcxproj.filters +0 -74
- package/libusb/msvc/listdevs_2010.vcxproj.filters +0 -14
- package/libusb/msvc/listdevs_2012.vcxproj.filters +0 -14
- package/libusb/msvc/stress_2010.vcxproj.filters +0 -25
- package/libusb/msvc/stress_2012.vcxproj.filters +0 -25
- package/libusb/msvc/xusb_2010.vcxproj.filters +0 -14
- package/libusb/msvc/xusb_2012.vcxproj.filters +0 -14
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/*
|
|
2
|
+
*
|
|
3
|
+
* Copyright (c) 2016, Oracle and/or its affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This library is free software; you can redistribute it and/or
|
|
6
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
7
|
+
* License as published by the Free Software Foundation; either
|
|
8
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
9
|
+
*
|
|
10
|
+
* This library is distributed in the hope that it will be useful,
|
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
13
|
+
* Lesser General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
16
|
+
* License along with this library; if not, write to the Free Software
|
|
17
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
#ifndef LIBUSB_SUNOS_H
|
|
21
|
+
#define LIBUSB_SUNOS_H
|
|
22
|
+
|
|
23
|
+
#include <libdevinfo.h>
|
|
24
|
+
#include <pthread.h>
|
|
25
|
+
#include "libusbi.h"
|
|
26
|
+
|
|
27
|
+
#define READ 0
|
|
28
|
+
#define WRITE 1
|
|
29
|
+
|
|
30
|
+
typedef struct sunos_device_priv {
|
|
31
|
+
uint8_t cfgvalue; /* active config value */
|
|
32
|
+
uint8_t *raw_cfgdescr; /* active config descriptor */
|
|
33
|
+
struct libusb_device_descriptor dev_descr; /* usb device descriptor */
|
|
34
|
+
char *ugenpath; /* name of the ugen(4) node */
|
|
35
|
+
char *phypath; /* physical path */
|
|
36
|
+
} sunos_dev_priv_t;
|
|
37
|
+
|
|
38
|
+
typedef struct endpoint {
|
|
39
|
+
int datafd; /* data file */
|
|
40
|
+
int statfd; /* state file */
|
|
41
|
+
} sunos_ep_priv_t;
|
|
42
|
+
|
|
43
|
+
typedef struct sunos_device_handle_priv {
|
|
44
|
+
uint8_t altsetting[USB_MAXINTERFACES]; /* a interface's alt */
|
|
45
|
+
uint8_t config_index;
|
|
46
|
+
sunos_ep_priv_t eps[USB_MAXENDPOINTS];
|
|
47
|
+
sunos_dev_priv_t *dpriv; /* device private */
|
|
48
|
+
} sunos_dev_handle_priv_t;
|
|
49
|
+
|
|
50
|
+
typedef struct sunos_transfer_priv {
|
|
51
|
+
struct aiocb aiocb;
|
|
52
|
+
struct libusb_transfer *transfer;
|
|
53
|
+
} sunos_xfer_priv_t;
|
|
54
|
+
|
|
55
|
+
struct node_args {
|
|
56
|
+
struct libusb_context *ctx;
|
|
57
|
+
struct discovered_devs **discdevs;
|
|
58
|
+
const char *last_ugenpath;
|
|
59
|
+
di_devlink_handle_t dlink_hdl;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
struct devlink_cbarg {
|
|
63
|
+
struct node_args *nargs; /* di node walk arguments */
|
|
64
|
+
di_node_t myself; /* the di node */
|
|
65
|
+
di_minor_t minor;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
typedef struct walk_link {
|
|
69
|
+
char *path;
|
|
70
|
+
int len;
|
|
71
|
+
char **linkpp;
|
|
72
|
+
} walk_link_t;
|
|
73
|
+
|
|
74
|
+
/* AIO callback args */
|
|
75
|
+
struct aio_callback_args{
|
|
76
|
+
struct libusb_transfer *transfer;
|
|
77
|
+
struct aiocb aiocb;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
#endif /* LIBUSB_SUNOS_H */
|
|
@@ -19,50 +19,47 @@
|
|
|
19
19
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
+
#include <config.h>
|
|
23
|
+
|
|
24
|
+
#include <time.h>
|
|
22
25
|
#if defined(__linux__) || defined(__OpenBSD__)
|
|
23
|
-
# if defined(
|
|
24
|
-
# define _GNU_SOURCE
|
|
25
|
-
# else
|
|
26
|
+
# if defined(__OpenBSD__)
|
|
26
27
|
# define _BSD_SOURCE
|
|
27
28
|
# endif
|
|
28
29
|
# include <unistd.h>
|
|
29
30
|
# include <sys/syscall.h>
|
|
30
31
|
#elif defined(__APPLE__)
|
|
31
|
-
# include <
|
|
32
|
+
# include <pthread.h>
|
|
32
33
|
#elif defined(__CYGWIN__)
|
|
33
34
|
# include <windows.h>
|
|
34
35
|
#endif
|
|
35
36
|
|
|
36
37
|
#include "threads_posix.h"
|
|
38
|
+
#include "libusbi.h"
|
|
37
39
|
|
|
38
|
-
int
|
|
40
|
+
int usbi_cond_timedwait(pthread_cond_t *cond,
|
|
41
|
+
pthread_mutex_t *mutex, const struct timeval *tv)
|
|
39
42
|
{
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (!attr) {
|
|
43
|
-
attr = &stack_attr;
|
|
44
|
-
err = pthread_mutexattr_init(&stack_attr);
|
|
45
|
-
if (err != 0)
|
|
46
|
-
return err;
|
|
47
|
-
}
|
|
43
|
+
struct timespec timeout;
|
|
44
|
+
int r;
|
|
48
45
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
goto finish;
|
|
46
|
+
r = usbi_backend.clock_gettime(USBI_CLOCK_REALTIME, &timeout);
|
|
47
|
+
if (r < 0)
|
|
48
|
+
return r;
|
|
53
49
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
50
|
+
timeout.tv_sec += tv->tv_sec;
|
|
51
|
+
timeout.tv_nsec += tv->tv_usec * 1000;
|
|
52
|
+
while (timeout.tv_nsec >= 1000000000L) {
|
|
53
|
+
timeout.tv_nsec -= 1000000000L;
|
|
54
|
+
timeout.tv_sec++;
|
|
55
|
+
}
|
|
59
56
|
|
|
60
|
-
return
|
|
57
|
+
return pthread_cond_timedwait(cond, mutex, &timeout);
|
|
61
58
|
}
|
|
62
59
|
|
|
63
60
|
int usbi_get_tid(void)
|
|
64
61
|
{
|
|
65
|
-
int ret
|
|
62
|
+
int ret;
|
|
66
63
|
#if defined(__ANDROID__)
|
|
67
64
|
ret = gettid();
|
|
68
65
|
#elif defined(__linux__)
|
|
@@ -72,10 +69,11 @@ int usbi_get_tid(void)
|
|
|
72
69
|
real thread support. For 5.1 and earlier, -1 is returned. */
|
|
73
70
|
ret = syscall(SYS_getthrid);
|
|
74
71
|
#elif defined(__APPLE__)
|
|
75
|
-
ret =
|
|
76
|
-
mach_port_deallocate(mach_task_self(), ret);
|
|
72
|
+
ret = (int)pthread_mach_thread_np(pthread_self());
|
|
77
73
|
#elif defined(__CYGWIN__)
|
|
78
74
|
ret = GetCurrentThreadId();
|
|
75
|
+
#else
|
|
76
|
+
ret = -1;
|
|
79
77
|
#endif
|
|
80
78
|
/* TODO: NetBSD thread ID support */
|
|
81
79
|
return ret;
|
|
@@ -22,28 +22,80 @@
|
|
|
22
22
|
#define LIBUSB_THREADS_POSIX_H
|
|
23
23
|
|
|
24
24
|
#include <pthread.h>
|
|
25
|
+
#ifdef HAVE_SYS_TIME_H
|
|
26
|
+
#include <sys/time.h>
|
|
27
|
+
#endif
|
|
25
28
|
|
|
26
|
-
#define
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
29
|
+
#define USBI_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
|
30
|
+
typedef pthread_mutex_t usbi_mutex_static_t;
|
|
31
|
+
static inline void usbi_mutex_static_lock(usbi_mutex_static_t *mutex)
|
|
32
|
+
{
|
|
33
|
+
(void)pthread_mutex_lock(mutex);
|
|
34
|
+
}
|
|
35
|
+
static inline void usbi_mutex_static_unlock(usbi_mutex_static_t *mutex)
|
|
36
|
+
{
|
|
37
|
+
(void)pthread_mutex_unlock(mutex);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
typedef pthread_mutex_t usbi_mutex_t;
|
|
41
|
+
static inline int usbi_mutex_init(usbi_mutex_t *mutex)
|
|
42
|
+
{
|
|
43
|
+
return pthread_mutex_init(mutex, NULL);
|
|
44
|
+
}
|
|
45
|
+
static inline void usbi_mutex_lock(usbi_mutex_t *mutex)
|
|
46
|
+
{
|
|
47
|
+
(void)pthread_mutex_lock(mutex);
|
|
48
|
+
}
|
|
49
|
+
static inline void usbi_mutex_unlock(usbi_mutex_t *mutex)
|
|
50
|
+
{
|
|
51
|
+
(void)pthread_mutex_unlock(mutex);
|
|
52
|
+
}
|
|
53
|
+
static inline int usbi_mutex_trylock(usbi_mutex_t *mutex)
|
|
54
|
+
{
|
|
55
|
+
return pthread_mutex_trylock(mutex);
|
|
56
|
+
}
|
|
57
|
+
static inline void usbi_mutex_destroy(usbi_mutex_t *mutex)
|
|
58
|
+
{
|
|
59
|
+
(void)pthread_mutex_destroy(mutex);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
typedef pthread_cond_t usbi_cond_t;
|
|
63
|
+
static inline void usbi_cond_init(pthread_cond_t *cond)
|
|
64
|
+
{
|
|
65
|
+
(void)pthread_cond_init(cond, NULL);
|
|
66
|
+
}
|
|
67
|
+
static inline int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex)
|
|
68
|
+
{
|
|
69
|
+
return pthread_cond_wait(cond, mutex);
|
|
70
|
+
}
|
|
71
|
+
int usbi_cond_timedwait(usbi_cond_t *cond,
|
|
72
|
+
usbi_mutex_t *mutex, const struct timeval *tv);
|
|
73
|
+
static inline void usbi_cond_broadcast(usbi_cond_t *cond)
|
|
74
|
+
{
|
|
75
|
+
(void)pthread_cond_broadcast(cond);
|
|
76
|
+
}
|
|
77
|
+
static inline void usbi_cond_destroy(usbi_cond_t *cond)
|
|
78
|
+
{
|
|
79
|
+
(void)pthread_cond_destroy(cond);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
typedef pthread_key_t usbi_tls_key_t;
|
|
83
|
+
static inline void usbi_tls_key_create(usbi_tls_key_t *key)
|
|
84
|
+
{
|
|
85
|
+
(void)pthread_key_create(key, NULL);
|
|
86
|
+
}
|
|
87
|
+
static inline void *usbi_tls_key_get(usbi_tls_key_t key)
|
|
88
|
+
{
|
|
89
|
+
return pthread_getspecific(key);
|
|
90
|
+
}
|
|
91
|
+
static inline void usbi_tls_key_set(usbi_tls_key_t key, void *ptr)
|
|
92
|
+
{
|
|
93
|
+
(void)pthread_setspecific(key, ptr);
|
|
94
|
+
}
|
|
95
|
+
static inline void usbi_tls_key_delete(usbi_tls_key_t key)
|
|
96
|
+
{
|
|
97
|
+
(void)pthread_key_delete(key);
|
|
98
|
+
}
|
|
47
99
|
|
|
48
100
|
int usbi_get_tid(void);
|
|
49
101
|
|
|
@@ -19,194 +19,108 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
#include <config.h>
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
#include <errno.h>
|
|
24
|
-
#include <stdarg.h>
|
|
25
24
|
|
|
26
25
|
#include "libusbi.h"
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
UNUSED(attr);
|
|
33
|
-
if(! mutex) return ((errno=EINVAL));
|
|
34
|
-
*mutex = CreateMutex(NULL, FALSE, NULL);
|
|
35
|
-
if(!*mutex) return ((errno=ENOMEM));
|
|
36
|
-
return 0;
|
|
37
|
-
}
|
|
38
|
-
int usbi_mutex_destroy(usbi_mutex_t *mutex) {
|
|
39
|
-
// It is not clear if CloseHandle failure is due to failure to unlock.
|
|
40
|
-
// If so, this should be errno=EBUSY.
|
|
41
|
-
if(!mutex || !CloseHandle(*mutex)) return ((errno=EINVAL));
|
|
42
|
-
*mutex = NULL;
|
|
43
|
-
return 0;
|
|
44
|
-
}
|
|
45
|
-
int usbi_mutex_trylock(usbi_mutex_t *mutex) {
|
|
46
|
-
DWORD result;
|
|
47
|
-
if(!mutex) return ((errno=EINVAL));
|
|
48
|
-
result = WaitForSingleObject(*mutex, 0);
|
|
49
|
-
if(result == WAIT_OBJECT_0 || result == WAIT_ABANDONED)
|
|
50
|
-
return 0; // acquired (ToDo: check that abandoned is ok)
|
|
51
|
-
if(result == WAIT_TIMEOUT)
|
|
52
|
-
return ((errno=EBUSY));
|
|
53
|
-
return ((errno=EINVAL)); // don't know how this would happen
|
|
54
|
-
// so don't know proper errno
|
|
55
|
-
}
|
|
56
|
-
int usbi_mutex_lock(usbi_mutex_t *mutex) {
|
|
57
|
-
DWORD result;
|
|
58
|
-
if(!mutex) return ((errno=EINVAL));
|
|
59
|
-
result = WaitForSingleObject(*mutex, INFINITE);
|
|
60
|
-
if(result == WAIT_OBJECT_0 || result == WAIT_ABANDONED)
|
|
61
|
-
return 0; // acquired (ToDo: check that abandoned is ok)
|
|
62
|
-
return ((errno=EINVAL)); // don't know how this would happen
|
|
63
|
-
// so don't know proper errno
|
|
64
|
-
}
|
|
65
|
-
int usbi_mutex_unlock(usbi_mutex_t *mutex) {
|
|
66
|
-
if(!mutex) return ((errno=EINVAL));
|
|
67
|
-
if(!ReleaseMutex(*mutex)) return ((errno=EPERM ));
|
|
68
|
-
return 0;
|
|
69
|
-
}
|
|
27
|
+
struct usbi_cond_perthread {
|
|
28
|
+
struct list_head list;
|
|
29
|
+
HANDLE event;
|
|
30
|
+
};
|
|
70
31
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
while (InterlockedExchange(
|
|
32
|
+
void usbi_mutex_static_lock(usbi_mutex_static_t *mutex)
|
|
33
|
+
{
|
|
34
|
+
while (InterlockedExchange(mutex, 1L) == 1L)
|
|
74
35
|
SleepEx(0, TRUE);
|
|
75
|
-
}
|
|
76
|
-
return 0;
|
|
77
|
-
}
|
|
78
|
-
int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex) {
|
|
79
|
-
if(!mutex) return ((errno=EINVAL));
|
|
80
|
-
*mutex = 0;
|
|
81
|
-
return 0;
|
|
82
36
|
}
|
|
83
37
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if(!cond) return ((errno=EINVAL));
|
|
88
|
-
list_init(&cond->waiters );
|
|
38
|
+
void usbi_cond_init(usbi_cond_t *cond)
|
|
39
|
+
{
|
|
40
|
+
list_init(&cond->waiters);
|
|
89
41
|
list_init(&cond->not_waiting);
|
|
90
|
-
return 0;
|
|
91
|
-
}
|
|
92
|
-
int usbi_cond_destroy(usbi_cond_t *cond) {
|
|
93
|
-
// This assumes no one is using this anymore. The check MAY NOT BE safe.
|
|
94
|
-
struct usbi_cond_perthread *pos, *next_pos = NULL;
|
|
95
|
-
if(!cond) return ((errno=EINVAL));
|
|
96
|
-
if(!list_empty(&cond->waiters)) return ((errno=EBUSY )); // (!see above!)
|
|
97
|
-
list_for_each_entry_safe(pos, next_pos, &cond->not_waiting, list, struct usbi_cond_perthread) {
|
|
98
|
-
CloseHandle(pos->event);
|
|
99
|
-
list_del(&pos->list);
|
|
100
|
-
free(pos);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return 0;
|
|
104
42
|
}
|
|
105
43
|
|
|
106
|
-
int
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
// primitives to the CV definition!
|
|
110
|
-
int fail = 0;
|
|
111
|
-
struct usbi_cond_perthread *pos;
|
|
112
|
-
if(!cond) return ((errno=EINVAL));
|
|
113
|
-
list_for_each_entry(pos, &cond->waiters, list, struct usbi_cond_perthread) {
|
|
114
|
-
if(!SetEvent(pos->event))
|
|
115
|
-
fail = 1;
|
|
116
|
-
}
|
|
117
|
-
// The wait function will remove its respective item from the list.
|
|
118
|
-
return fail ? ((errno=EINVAL)) : 0;
|
|
119
|
-
}
|
|
120
|
-
int usbi_cond_signal(usbi_cond_t *cond) {
|
|
121
|
-
// Assumes mutex is locked; this is not in keeping with POSIX spec, but
|
|
122
|
-
// libusb does this anyway, so we simplify by not adding more sync
|
|
123
|
-
// primitives to the CV definition!
|
|
44
|
+
static int usbi_cond_intwait(usbi_cond_t *cond,
|
|
45
|
+
usbi_mutex_t *mutex, DWORD timeout_ms)
|
|
46
|
+
{
|
|
124
47
|
struct usbi_cond_perthread *pos;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
usbi_mutex_t *mutex,
|
|
133
|
-
DWORD timeout_ms) {
|
|
134
|
-
struct usbi_cond_perthread *pos;
|
|
135
|
-
int found = 0, r;
|
|
136
|
-
DWORD r2,tid = GetCurrentThreadId();
|
|
137
|
-
if(!cond || !mutex) return ((errno=EINVAL));
|
|
138
|
-
list_for_each_entry(pos, &cond->not_waiting, list, struct usbi_cond_perthread) {
|
|
139
|
-
if(tid == pos->tid) {
|
|
140
|
-
found = 1;
|
|
141
|
-
break;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
if(!found) {
|
|
145
|
-
pos = (struct usbi_cond_perthread*) calloc(1, sizeof(struct usbi_cond_perthread));
|
|
146
|
-
if(!pos) return ((errno=ENOMEM)); // This errno is not POSIX-allowed.
|
|
147
|
-
pos->tid = tid;
|
|
48
|
+
DWORD r;
|
|
49
|
+
|
|
50
|
+
// Same assumption as usbi_cond_broadcast() holds
|
|
51
|
+
if (list_empty(&cond->not_waiting)) {
|
|
52
|
+
pos = malloc(sizeof(*pos));
|
|
53
|
+
if (pos == NULL)
|
|
54
|
+
return ENOMEM; // This errno is not POSIX-allowed.
|
|
148
55
|
pos->event = CreateEvent(NULL, FALSE, FALSE, NULL); // auto-reset.
|
|
149
|
-
if(
|
|
56
|
+
if (pos->event == NULL) {
|
|
150
57
|
free(pos);
|
|
151
|
-
return
|
|
58
|
+
return ENOMEM;
|
|
152
59
|
}
|
|
153
|
-
|
|
60
|
+
} else {
|
|
61
|
+
pos = list_first_entry(&cond->not_waiting, struct usbi_cond_perthread, list);
|
|
62
|
+
list_del(&pos->list); // remove from not_waiting list.
|
|
63
|
+
// Ensure the event is clear before waiting
|
|
64
|
+
WaitForSingleObject(pos->event, 0);
|
|
154
65
|
}
|
|
155
66
|
|
|
156
|
-
list_del(&pos->list); // remove from not_waiting list.
|
|
157
67
|
list_add(&pos->list, &cond->waiters);
|
|
158
68
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
r = usbi_mutex_lock(mutex);
|
|
163
|
-
if(r) return r;
|
|
69
|
+
LeaveCriticalSection(mutex);
|
|
70
|
+
r = WaitForSingleObject(pos->event, timeout_ms);
|
|
71
|
+
EnterCriticalSection(mutex);
|
|
164
72
|
|
|
165
73
|
list_del(&pos->list);
|
|
166
74
|
list_add(&pos->list, &cond->not_waiting);
|
|
167
75
|
|
|
168
|
-
if(
|
|
169
|
-
|
|
170
|
-
|
|
76
|
+
if (r == WAIT_OBJECT_0)
|
|
77
|
+
return 0;
|
|
78
|
+
else if (r == WAIT_TIMEOUT)
|
|
79
|
+
return ETIMEDOUT;
|
|
80
|
+
else
|
|
81
|
+
return EINVAL;
|
|
171
82
|
}
|
|
83
|
+
|
|
172
84
|
// N.B.: usbi_cond_*wait() can also return ENOMEM, even though pthread_cond_*wait cannot!
|
|
173
|
-
int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex)
|
|
85
|
+
int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex)
|
|
86
|
+
{
|
|
174
87
|
return usbi_cond_intwait(cond, mutex, INFINITE);
|
|
175
88
|
}
|
|
89
|
+
|
|
176
90
|
int usbi_cond_timedwait(usbi_cond_t *cond,
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
FILETIME filetime;
|
|
180
|
-
ULARGE_INTEGER rtime;
|
|
181
|
-
struct timeval targ_time, cur_time, delta_time;
|
|
182
|
-
struct timespec cur_time_ns;
|
|
91
|
+
usbi_mutex_t *mutex, const struct timeval *tv)
|
|
92
|
+
{
|
|
183
93
|
DWORD millis;
|
|
184
94
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
rtime.LowPart = filetime.dwLowDateTime;
|
|
190
|
-
rtime.HighPart = filetime.dwHighDateTime;
|
|
191
|
-
rtime.QuadPart -= epoch_time;
|
|
192
|
-
cur_time_ns.tv_sec = (long)(rtime.QuadPart / 10000000);
|
|
193
|
-
cur_time_ns.tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
|
|
194
|
-
TIMESPEC_TO_TIMEVAL(&cur_time, &cur_time_ns);
|
|
195
|
-
|
|
196
|
-
TIMESPEC_TO_TIMEVAL(&targ_time, abstime);
|
|
197
|
-
timersub(&targ_time, &cur_time, &delta_time);
|
|
198
|
-
if(delta_time.tv_sec < 0) // abstime already passed?
|
|
199
|
-
millis = 0;
|
|
200
|
-
else {
|
|
201
|
-
millis = delta_time.tv_usec/1000;
|
|
202
|
-
millis += delta_time.tv_sec *1000;
|
|
203
|
-
if (delta_time.tv_usec % 1000) // round up to next millisecond
|
|
204
|
-
millis++;
|
|
205
|
-
}
|
|
206
|
-
|
|
95
|
+
millis = (DWORD)(tv->tv_sec * 1000) + (tv->tv_usec / 1000);
|
|
96
|
+
/* round up to next millisecond */
|
|
97
|
+
if (tv->tv_usec % 1000)
|
|
98
|
+
millis++;
|
|
207
99
|
return usbi_cond_intwait(cond, mutex, millis);
|
|
208
100
|
}
|
|
209
101
|
|
|
210
|
-
|
|
211
|
-
|
|
102
|
+
void usbi_cond_broadcast(usbi_cond_t *cond)
|
|
103
|
+
{
|
|
104
|
+
// Assumes mutex is locked; this is not in keeping with POSIX spec, but
|
|
105
|
+
// libusb does this anyway, so we simplify by not adding more sync
|
|
106
|
+
// primitives to the CV definition!
|
|
107
|
+
struct usbi_cond_perthread *pos;
|
|
108
|
+
|
|
109
|
+
list_for_each_entry(pos, &cond->waiters, list, struct usbi_cond_perthread)
|
|
110
|
+
SetEvent(pos->event);
|
|
111
|
+
// The wait function will remove its respective item from the list.
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
void usbi_cond_destroy(usbi_cond_t *cond)
|
|
115
|
+
{
|
|
116
|
+
// This assumes no one is using this anymore. The check MAY NOT BE safe.
|
|
117
|
+
struct usbi_cond_perthread *pos, *next;
|
|
118
|
+
|
|
119
|
+
if (!list_empty(&cond->waiters))
|
|
120
|
+
return; // (!see above!)
|
|
121
|
+
list_for_each_entry_safe(pos, next, &cond->not_waiting, list, struct usbi_cond_perthread) {
|
|
122
|
+
CloseHandle(pos->event);
|
|
123
|
+
list_del(&pos->list);
|
|
124
|
+
free(pos);
|
|
125
|
+
}
|
|
212
126
|
}
|
|
@@ -21,67 +21,91 @@
|
|
|
21
21
|
#ifndef LIBUSB_THREADS_WINDOWS_H
|
|
22
22
|
#define LIBUSB_THREADS_WINDOWS_H
|
|
23
23
|
|
|
24
|
-
#define
|
|
25
|
-
#
|
|
26
|
-
|
|
27
|
-
#
|
|
24
|
+
#define USBI_MUTEX_INITIALIZER 0L
|
|
25
|
+
#ifdef _WIN32_WCE
|
|
26
|
+
typedef LONG usbi_mutex_static_t;
|
|
27
|
+
#else
|
|
28
|
+
typedef volatile LONG usbi_mutex_static_t;
|
|
29
|
+
#endif
|
|
30
|
+
void usbi_mutex_static_lock(usbi_mutex_static_t *mutex);
|
|
31
|
+
static inline void usbi_mutex_static_unlock(usbi_mutex_static_t *mutex)
|
|
32
|
+
{
|
|
33
|
+
InterlockedExchange(mutex, 0L);
|
|
34
|
+
}
|
|
28
35
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
typedef CRITICAL_SECTION usbi_mutex_t;
|
|
37
|
+
static inline int usbi_mutex_init(usbi_mutex_t *mutex)
|
|
38
|
+
{
|
|
39
|
+
InitializeCriticalSection(mutex);
|
|
40
|
+
return 0;
|
|
41
|
+
}
|
|
42
|
+
static inline void usbi_mutex_lock(usbi_mutex_t *mutex)
|
|
43
|
+
{
|
|
44
|
+
EnterCriticalSection(mutex);
|
|
45
|
+
}
|
|
46
|
+
static inline void usbi_mutex_unlock(usbi_mutex_t *mutex)
|
|
47
|
+
{
|
|
48
|
+
LeaveCriticalSection(mutex);
|
|
49
|
+
}
|
|
50
|
+
static inline int usbi_mutex_trylock(usbi_mutex_t *mutex)
|
|
51
|
+
{
|
|
52
|
+
return !TryEnterCriticalSection(mutex);
|
|
53
|
+
}
|
|
54
|
+
static inline void usbi_mutex_destroy(usbi_mutex_t *mutex)
|
|
55
|
+
{
|
|
56
|
+
DeleteCriticalSection(mutex);
|
|
57
|
+
}
|
|
42
58
|
|
|
43
59
|
// We *were* getting timespec from pthread.h:
|
|
44
60
|
#if (!defined(HAVE_STRUCT_TIMESPEC) && !defined(_TIMESPEC_DEFINED))
|
|
45
61
|
#define HAVE_STRUCT_TIMESPEC 1
|
|
46
62
|
#define _TIMESPEC_DEFINED 1
|
|
47
63
|
struct timespec {
|
|
48
|
-
|
|
49
|
-
|
|
64
|
+
long tv_sec;
|
|
65
|
+
long tv_nsec;
|
|
50
66
|
};
|
|
51
67
|
#endif /* HAVE_STRUCT_TIMESPEC | _TIMESPEC_DEFINED */
|
|
52
68
|
|
|
53
69
|
// We *were* getting ETIMEDOUT from pthread.h:
|
|
54
70
|
#ifndef ETIMEDOUT
|
|
55
|
-
#
|
|
71
|
+
#define ETIMEDOUT 10060 /* This is the value in winsock.h. */
|
|
56
72
|
#endif
|
|
57
73
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
int usbi_mutex_static_lock(usbi_mutex_static_t *mutex);
|
|
65
|
-
int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
int usbi_mutex_init(usbi_mutex_t *mutex,
|
|
69
|
-
const usbi_mutexattr_t *attr);
|
|
70
|
-
int usbi_mutex_lock(usbi_mutex_t *mutex);
|
|
71
|
-
int usbi_mutex_unlock(usbi_mutex_t *mutex);
|
|
72
|
-
int usbi_mutex_trylock(usbi_mutex_t *mutex);
|
|
73
|
-
int usbi_mutex_destroy(usbi_mutex_t *mutex);
|
|
74
|
+
typedef struct usbi_cond {
|
|
75
|
+
// Every time a thread touches the CV, it winds up in one of these lists.
|
|
76
|
+
// It stays there until the CV is destroyed, even if the thread terminates.
|
|
77
|
+
struct list_head waiters;
|
|
78
|
+
struct list_head not_waiting;
|
|
79
|
+
} usbi_cond_t;
|
|
74
80
|
|
|
75
|
-
|
|
76
|
-
const usbi_condattr_t *attr);
|
|
77
|
-
int usbi_cond_destroy(usbi_cond_t *cond);
|
|
81
|
+
void usbi_cond_init(usbi_cond_t *cond);
|
|
78
82
|
int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex);
|
|
79
83
|
int usbi_cond_timedwait(usbi_cond_t *cond,
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
usbi_mutex_t *mutex, const struct timeval *tv);
|
|
85
|
+
void usbi_cond_broadcast(usbi_cond_t *cond);
|
|
86
|
+
void usbi_cond_destroy(usbi_cond_t *cond);
|
|
87
|
+
|
|
88
|
+
typedef DWORD usbi_tls_key_t;
|
|
89
|
+
static inline void usbi_tls_key_create(usbi_tls_key_t *key)
|
|
90
|
+
{
|
|
91
|
+
*key = TlsAlloc();
|
|
92
|
+
}
|
|
93
|
+
static inline void *usbi_tls_key_get(usbi_tls_key_t key)
|
|
94
|
+
{
|
|
95
|
+
return TlsGetValue(key);
|
|
96
|
+
}
|
|
97
|
+
static inline void usbi_tls_key_set(usbi_tls_key_t key, void *ptr)
|
|
98
|
+
{
|
|
99
|
+
(void)TlsSetValue(key, ptr);
|
|
100
|
+
}
|
|
101
|
+
static inline void usbi_tls_key_delete(usbi_tls_key_t key)
|
|
102
|
+
{
|
|
103
|
+
(void)TlsFree(key);
|
|
104
|
+
}
|
|
84
105
|
|
|
85
|
-
int usbi_get_tid(void)
|
|
106
|
+
static inline int usbi_get_tid(void)
|
|
107
|
+
{
|
|
108
|
+
return (int)GetCurrentThreadId();
|
|
109
|
+
}
|
|
86
110
|
|
|
87
111
|
#endif /* LIBUSB_THREADS_WINDOWS_H */
|