usb 1.7.2-prebuild
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/.github/workflows/prebuild.yml +62 -0
- package/.gitmodules +3 -0
- package/LICENSE +7 -0
- package/Readme.md +339 -0
- package/binding.gyp +90 -0
- package/libusb/.gitattributes +11 -0
- package/libusb/.private/README.txt +5 -0
- package/libusb/.private/bd.cmd +89 -0
- package/libusb/.private/bm.sh +54 -0
- package/libusb/.private/bwince.cmd +57 -0
- package/libusb/.private/post-rewrite.sh +28 -0
- package/libusb/.private/pre-commit.sh +42 -0
- package/libusb/.private/wbs.txt +61 -0
- package/libusb/.private/wbs_wince.txt +42 -0
- package/libusb/AUTHORS +78 -0
- package/libusb/COPYING +504 -0
- package/libusb/ChangeLog +211 -0
- package/libusb/INSTALL +234 -0
- package/libusb/INSTALL_WIN.txt +73 -0
- package/libusb/Makefile.am +28 -0
- package/libusb/NEWS +2 -0
- package/libusb/PORTING +94 -0
- package/libusb/README +28 -0
- package/libusb/README.git +41 -0
- package/libusb/TODO +2 -0
- package/libusb/Xcode/common.xcconfig +49 -0
- package/libusb/Xcode/debug.xcconfig +29 -0
- package/libusb/Xcode/libusb.xcconfig +21 -0
- package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +1 -0
- package/libusb/Xcode/libusb_debug.xcconfig +21 -0
- package/libusb/Xcode/libusb_release.xcconfig +21 -0
- package/libusb/Xcode/release.xcconfig +30 -0
- package/libusb/android/README +114 -0
- package/libusb/android/jni/Android.mk +23 -0
- package/libusb/android/jni/Application.mk +24 -0
- package/libusb/android/jni/examples.mk +134 -0
- package/libusb/android/jni/libusb.mk +54 -0
- package/libusb/android/jni/tests.mk +56 -0
- package/libusb/autogen.sh +8 -0
- package/libusb/bootstrap.sh +19 -0
- package/libusb/configure.ac +304 -0
- package/libusb/doc/Makefile.am +9 -0
- package/libusb/doc/doxygen.cfg.in +1288 -0
- package/libusb/doc/libusb.png +0 -0
- package/libusb/examples/Makefile.am +19 -0
- package/libusb/examples/dpfp.c +506 -0
- package/libusb/examples/dpfp_threaded.c +544 -0
- package/libusb/examples/ezusb.c +831 -0
- package/libusb/examples/ezusb.h +120 -0
- package/libusb/examples/fxload.c +287 -0
- package/libusb/examples/getopt/getopt.c +1060 -0
- package/libusb/examples/getopt/getopt.h +180 -0
- package/libusb/examples/getopt/getopt1.c +188 -0
- package/libusb/examples/hotplugtest.c +104 -0
- package/libusb/examples/listdevs.c +71 -0
- package/libusb/examples/sam3u_benchmark.c +193 -0
- package/libusb/examples/xusb.c +1129 -0
- package/libusb/libusb/Makefile.am +75 -0
- package/libusb/libusb/core.c +2342 -0
- package/libusb/libusb/descriptor.c +1199 -0
- package/libusb/libusb/hotplug.c +327 -0
- package/libusb/libusb/hotplug.h +82 -0
- package/libusb/libusb/io.c +2631 -0
- package/libusb/libusb/libusb-1.0.def +166 -0
- package/libusb/libusb/libusb-1.0.rc +61 -0
- package/libusb/libusb/libusb.h +1998 -0
- package/libusb/libusb/libusbi.h +1040 -0
- package/libusb/libusb/os/darwin_usb.c +2009 -0
- package/libusb/libusb/os/darwin_usb.h +162 -0
- package/libusb/libusb/os/linux_netlink.c +369 -0
- package/libusb/libusb/os/linux_udev.c +307 -0
- package/libusb/libusb/os/linux_usbfs.c +2695 -0
- package/libusb/libusb/os/linux_usbfs.h +192 -0
- package/libusb/libusb/os/netbsd_usb.c +738 -0
- package/libusb/libusb/os/openbsd_usb.c +832 -0
- package/libusb/libusb/os/poll_posix.c +51 -0
- package/libusb/libusb/os/poll_posix.h +11 -0
- package/libusb/libusb/os/poll_windows.c +796 -0
- package/libusb/libusb/os/poll_windows.h +131 -0
- package/libusb/libusb/os/threads_posix.c +82 -0
- package/libusb/libusb/os/threads_posix.h +50 -0
- package/libusb/libusb/os/threads_windows.c +212 -0
- package/libusb/libusb/os/threads_windows.h +87 -0
- package/libusb/libusb/os/wince_usb.c +1032 -0
- package/libusb/libusb/os/wince_usb.h +131 -0
- package/libusb/libusb/os/windows_common.h +108 -0
- package/libusb/libusb/os/windows_usb.c +5347 -0
- package/libusb/libusb/os/windows_usb.h +971 -0
- package/libusb/libusb/strerror.c +199 -0
- package/libusb/libusb/sync.c +307 -0
- package/libusb/libusb/version.h +18 -0
- package/libusb/libusb/version_nano.h +1 -0
- package/libusb/libusb-1.0.pc.in +11 -0
- package/libusb/msvc/config.h +50 -0
- package/libusb/msvc/ddk_build.cmd +175 -0
- package/libusb/msvc/errno.h +102 -0
- package/libusb/msvc/fxload_2010.vcxproj +170 -0
- package/libusb/msvc/fxload_2010.vcxproj.filters +25 -0
- package/libusb/msvc/fxload_2012.vcxproj +174 -0
- package/libusb/msvc/fxload_2012.vcxproj.filters +25 -0
- package/libusb/msvc/fxload_2013.vcxproj +174 -0
- package/libusb/msvc/fxload_sources +23 -0
- package/libusb/msvc/getopt_2005.vcproj +288 -0
- package/libusb/msvc/getopt_2010.vcxproj +131 -0
- package/libusb/msvc/getopt_2010.vcxproj.filters +26 -0
- package/libusb/msvc/getopt_2012.vcxproj +136 -0
- package/libusb/msvc/getopt_2012.vcxproj.filters +26 -0
- package/libusb/msvc/getopt_2013.vcxproj +136 -0
- package/libusb/msvc/getopt_sources +20 -0
- package/libusb/msvc/hotplugtest_2010.vcxproj +163 -0
- package/libusb/msvc/hotplugtest_2010.vcxproj.filters +14 -0
- package/libusb/msvc/hotplugtest_2012.vcxproj +167 -0
- package/libusb/msvc/hotplugtest_2012.vcxproj.filters +14 -0
- package/libusb/msvc/hotplugtest_2013.vcxproj +167 -0
- package/libusb/msvc/hotplugtest_sources +20 -0
- package/libusb/msvc/inttypes.h +295 -0
- package/libusb/msvc/libusb.dsw +71 -0
- package/libusb/msvc/libusb_2005.sln +95 -0
- package/libusb/msvc/libusb_2010.sln +94 -0
- package/libusb/msvc/libusb_2012.sln +94 -0
- package/libusb/msvc/libusb_2013.sln +100 -0
- package/libusb/msvc/libusb_2015.sln +100 -0
- package/libusb/msvc/libusb_dll.dsp +194 -0
- package/libusb/msvc/libusb_dll_2005.vcproj +436 -0
- package/libusb/msvc/libusb_dll_2010.vcxproj +170 -0
- package/libusb/msvc/libusb_dll_2010.vcxproj.filters +81 -0
- package/libusb/msvc/libusb_dll_2012.vcxproj +175 -0
- package/libusb/msvc/libusb_dll_2012.vcxproj.filters +84 -0
- package/libusb/msvc/libusb_dll_2013.vcxproj +175 -0
- package/libusb/msvc/libusb_dll_wince.vcproj +1243 -0
- package/libusb/msvc/libusb_sources +38 -0
- package/libusb/msvc/libusb_static.dsp +174 -0
- package/libusb/msvc/libusb_static_2005.vcproj +362 -0
- package/libusb/msvc/libusb_static_2010.vcxproj +156 -0
- package/libusb/msvc/libusb_static_2010.vcxproj.filters +74 -0
- package/libusb/msvc/libusb_static_2012.vcxproj +160 -0
- package/libusb/msvc/libusb_static_2012.vcxproj.filters +74 -0
- package/libusb/msvc/libusb_static_2013.vcxproj +160 -0
- package/libusb/msvc/libusb_static_wince.vcproj +1185 -0
- package/libusb/msvc/libusb_wince.sln +246 -0
- package/libusb/msvc/listdevs.dsp +103 -0
- package/libusb/msvc/listdevs_2005.vcproj +360 -0
- package/libusb/msvc/listdevs_2010.vcxproj +165 -0
- package/libusb/msvc/listdevs_2010.vcxproj.filters +14 -0
- package/libusb/msvc/listdevs_2012.vcxproj +169 -0
- package/libusb/msvc/listdevs_2012.vcxproj.filters +14 -0
- package/libusb/msvc/listdevs_2013.vcxproj +169 -0
- package/libusb/msvc/listdevs_sources +19 -0
- package/libusb/msvc/listdevs_wince.vcproj +1120 -0
- package/libusb/msvc/missing.c +80 -0
- package/libusb/msvc/missing.h +32 -0
- package/libusb/msvc/stdint.h +256 -0
- package/libusb/msvc/stress_2005.vcproj +390 -0
- package/libusb/msvc/stress_2010.vcxproj +167 -0
- package/libusb/msvc/stress_2010.vcxproj.filters +25 -0
- package/libusb/msvc/stress_2012.vcxproj +171 -0
- package/libusb/msvc/stress_2012.vcxproj.filters +25 -0
- package/libusb/msvc/stress_2013.vcxproj +171 -0
- package/libusb/msvc/stress_wince.vcproj +1128 -0
- package/libusb/msvc/xusb.dsp +102 -0
- package/libusb/msvc/xusb_2005.vcproj +344 -0
- package/libusb/msvc/xusb_2010.vcxproj +163 -0
- package/libusb/msvc/xusb_2010.vcxproj.filters +14 -0
- package/libusb/msvc/xusb_2012.vcxproj +167 -0
- package/libusb/msvc/xusb_2012.vcxproj.filters +14 -0
- package/libusb/msvc/xusb_2013.vcxproj +167 -0
- package/libusb/msvc/xusb_sources +20 -0
- package/libusb/msvc/xusb_wince.vcproj +1120 -0
- package/libusb/tests/Makefile.am +6 -0
- package/libusb/tests/libusb_testlib.h +107 -0
- package/libusb/tests/stress.c +160 -0
- package/libusb/tests/testlib.c +281 -0
- package/libusb.gypi +136 -0
- package/libusb_config/config.h +1 -0
- package/package.json +69 -0
- package/src/device.cc +412 -0
- package/src/helpers.h +64 -0
- package/src/node_usb.cc +319 -0
- package/src/node_usb.h +120 -0
- package/src/transfer.cc +148 -0
- package/src/uv_async_queue.h +33 -0
- package/test/usb.coffee +191 -0
- package/usb.js +524 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Windows compat: POSIX compatibility wrapper
|
|
3
|
+
* Copyright © 2012-2013 RealVNC Ltd.
|
|
4
|
+
* Copyright © 2009-2010 Pete Batard <pete@akeo.ie>
|
|
5
|
+
* With contributions from Michael Plante, Orin Eman et al.
|
|
6
|
+
* Parts of poll implementation from libusb-win32, by Stephan Meyer et al.
|
|
7
|
+
*
|
|
8
|
+
* This library is free software; you can redistribute it and/or
|
|
9
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
10
|
+
* License as published by the Free Software Foundation; either
|
|
11
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
12
|
+
*
|
|
13
|
+
* This library is distributed in the hope that it will be useful,
|
|
14
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
16
|
+
* Lesser General Public License for more details.
|
|
17
|
+
*
|
|
18
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
19
|
+
* License along with this library; if not, write to the Free Software
|
|
20
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
23
|
+
#pragma once
|
|
24
|
+
|
|
25
|
+
#if defined(_MSC_VER)
|
|
26
|
+
// disable /W4 MSVC warnings that are benign
|
|
27
|
+
#pragma warning(disable:4127) // conditional expression is constant
|
|
28
|
+
#endif
|
|
29
|
+
|
|
30
|
+
// Handle synchronous completion through the overlapped structure
|
|
31
|
+
#if !defined(STATUS_REPARSE) // reuse the REPARSE status code
|
|
32
|
+
#define STATUS_REPARSE ((LONG)0x00000104L)
|
|
33
|
+
#endif
|
|
34
|
+
#define STATUS_COMPLETED_SYNCHRONOUSLY STATUS_REPARSE
|
|
35
|
+
#if defined(_WIN32_WCE)
|
|
36
|
+
// WinCE doesn't have a HasOverlappedIoCompleted() macro, so attempt to emulate it
|
|
37
|
+
#define HasOverlappedIoCompleted(lpOverlapped) (((DWORD)(lpOverlapped)->Internal) != STATUS_PENDING)
|
|
38
|
+
#endif
|
|
39
|
+
#define HasOverlappedIoCompletedSync(lpOverlapped) (((DWORD)(lpOverlapped)->Internal) == STATUS_COMPLETED_SYNCHRONOUSLY)
|
|
40
|
+
|
|
41
|
+
#define DUMMY_HANDLE ((HANDLE)(LONG_PTR)-2)
|
|
42
|
+
|
|
43
|
+
/* Windows versions */
|
|
44
|
+
enum windows_version {
|
|
45
|
+
WINDOWS_CE = -2,
|
|
46
|
+
WINDOWS_UNDEFINED = -1,
|
|
47
|
+
WINDOWS_UNSUPPORTED = 0,
|
|
48
|
+
WINDOWS_XP = 0x51,
|
|
49
|
+
WINDOWS_2003 = 0x52, // Also XP x64
|
|
50
|
+
WINDOWS_VISTA = 0x60,
|
|
51
|
+
WINDOWS_7 = 0x61,
|
|
52
|
+
WINDOWS_8 = 0x62,
|
|
53
|
+
WINDOWS_8_1_OR_LATER = 0x63,
|
|
54
|
+
WINDOWS_MAX
|
|
55
|
+
};
|
|
56
|
+
extern int windows_version;
|
|
57
|
+
|
|
58
|
+
#define MAX_FDS 256
|
|
59
|
+
|
|
60
|
+
#define POLLIN 0x0001 /* There is data to read */
|
|
61
|
+
#define POLLPRI 0x0002 /* There is urgent data to read */
|
|
62
|
+
#define POLLOUT 0x0004 /* Writing now will not block */
|
|
63
|
+
#define POLLERR 0x0008 /* Error condition */
|
|
64
|
+
#define POLLHUP 0x0010 /* Hung up */
|
|
65
|
+
#define POLLNVAL 0x0020 /* Invalid request: fd not open */
|
|
66
|
+
|
|
67
|
+
struct pollfd {
|
|
68
|
+
int fd; /* file descriptor */
|
|
69
|
+
short events; /* requested events */
|
|
70
|
+
short revents; /* returned events */
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// access modes
|
|
74
|
+
enum rw_type {
|
|
75
|
+
RW_NONE,
|
|
76
|
+
RW_READ,
|
|
77
|
+
RW_WRITE,
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// fd struct that can be used for polling on Windows
|
|
81
|
+
typedef int cancel_transfer(struct usbi_transfer *itransfer);
|
|
82
|
+
|
|
83
|
+
struct winfd {
|
|
84
|
+
int fd; // what's exposed to libusb core
|
|
85
|
+
HANDLE handle; // what we need to attach overlapped to the I/O op, so we can poll it
|
|
86
|
+
OVERLAPPED* overlapped; // what will report our I/O status
|
|
87
|
+
struct usbi_transfer *itransfer; // Associated transfer, or NULL if completed
|
|
88
|
+
cancel_transfer *cancel_fn; // Function pointer to cancel transfer API
|
|
89
|
+
enum rw_type rw; // I/O transfer direction: read *XOR* write (NOT BOTH)
|
|
90
|
+
};
|
|
91
|
+
extern const struct winfd INVALID_WINFD;
|
|
92
|
+
|
|
93
|
+
int usbi_pipe(int pipefd[2]);
|
|
94
|
+
int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout);
|
|
95
|
+
ssize_t usbi_write(int fd, const void *buf, size_t count);
|
|
96
|
+
ssize_t usbi_read(int fd, void *buf, size_t count);
|
|
97
|
+
int usbi_close(int fd);
|
|
98
|
+
|
|
99
|
+
void init_polling(void);
|
|
100
|
+
void exit_polling(void);
|
|
101
|
+
struct winfd usbi_create_fd(HANDLE handle, int access_mode,
|
|
102
|
+
struct usbi_transfer *transfer, cancel_transfer *cancel_fn);
|
|
103
|
+
void usbi_free_fd(struct winfd* winfd);
|
|
104
|
+
struct winfd fd_to_winfd(int fd);
|
|
105
|
+
struct winfd handle_to_winfd(HANDLE handle);
|
|
106
|
+
struct winfd overlapped_to_winfd(OVERLAPPED* overlapped);
|
|
107
|
+
|
|
108
|
+
/*
|
|
109
|
+
* Timeval operations
|
|
110
|
+
*/
|
|
111
|
+
#if defined(DDKBUILD)
|
|
112
|
+
#include <winsock.h> // defines timeval functions on DDK
|
|
113
|
+
#endif
|
|
114
|
+
|
|
115
|
+
#if !defined(TIMESPEC_TO_TIMEVAL)
|
|
116
|
+
#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
|
|
117
|
+
(tv)->tv_sec = (long)(ts)->tv_sec; \
|
|
118
|
+
(tv)->tv_usec = (long)(ts)->tv_nsec / 1000; \
|
|
119
|
+
}
|
|
120
|
+
#endif
|
|
121
|
+
#if !defined(timersub)
|
|
122
|
+
#define timersub(a, b, result) \
|
|
123
|
+
do { \
|
|
124
|
+
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
|
|
125
|
+
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
|
|
126
|
+
if ((result)->tv_usec < 0) { \
|
|
127
|
+
--(result)->tv_sec; \
|
|
128
|
+
(result)->tv_usec += 1000000; \
|
|
129
|
+
} \
|
|
130
|
+
} while (0)
|
|
131
|
+
#endif
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* libusb synchronization using POSIX Threads
|
|
3
|
+
*
|
|
4
|
+
* Copyright © 2011 Vitali Lovich <vlovich@aliph.com>
|
|
5
|
+
* Copyright © 2011 Peter Stuge <peter@stuge.se>
|
|
6
|
+
*
|
|
7
|
+
* This library is free software; you can redistribute it and/or
|
|
8
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
9
|
+
* License as published by the Free Software Foundation; either
|
|
10
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
11
|
+
*
|
|
12
|
+
* This library is distributed in the hope that it will be useful,
|
|
13
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
15
|
+
* Lesser General Public License for more details.
|
|
16
|
+
*
|
|
17
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
18
|
+
* License along with this library; if not, write to the Free Software
|
|
19
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
#if defined(__linux__) || defined(__OpenBSD__)
|
|
23
|
+
# if defined(__linux__)
|
|
24
|
+
# define _GNU_SOURCE
|
|
25
|
+
# else
|
|
26
|
+
# define _BSD_SOURCE
|
|
27
|
+
# endif
|
|
28
|
+
# include <unistd.h>
|
|
29
|
+
# include <sys/syscall.h>
|
|
30
|
+
#elif defined(__APPLE__)
|
|
31
|
+
# include <mach/mach.h>
|
|
32
|
+
#elif defined(__CYGWIN__)
|
|
33
|
+
# include <windows.h>
|
|
34
|
+
#endif
|
|
35
|
+
|
|
36
|
+
#include "threads_posix.h"
|
|
37
|
+
|
|
38
|
+
int usbi_mutex_init_recursive(pthread_mutex_t *mutex, pthread_mutexattr_t *attr)
|
|
39
|
+
{
|
|
40
|
+
int err;
|
|
41
|
+
pthread_mutexattr_t stack_attr;
|
|
42
|
+
if (!attr) {
|
|
43
|
+
attr = &stack_attr;
|
|
44
|
+
err = pthread_mutexattr_init(&stack_attr);
|
|
45
|
+
if (err != 0)
|
|
46
|
+
return err;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* mutexattr_settype requires _GNU_SOURCE or _XOPEN_SOURCE >= 500 on Linux */
|
|
50
|
+
err = pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE);
|
|
51
|
+
if (err != 0)
|
|
52
|
+
goto finish;
|
|
53
|
+
|
|
54
|
+
err = pthread_mutex_init(mutex, attr);
|
|
55
|
+
|
|
56
|
+
finish:
|
|
57
|
+
if (attr == &stack_attr)
|
|
58
|
+
pthread_mutexattr_destroy(&stack_attr);
|
|
59
|
+
|
|
60
|
+
return err;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
int usbi_get_tid(void)
|
|
64
|
+
{
|
|
65
|
+
int ret = -1;
|
|
66
|
+
#if defined(__ANDROID__)
|
|
67
|
+
ret = gettid();
|
|
68
|
+
#elif defined(__linux__)
|
|
69
|
+
ret = syscall(SYS_gettid);
|
|
70
|
+
#elif defined(__OpenBSD__)
|
|
71
|
+
/* The following only works with OpenBSD > 5.1 as it requires
|
|
72
|
+
real thread support. For 5.1 and earlier, -1 is returned. */
|
|
73
|
+
ret = syscall(SYS_getthrid);
|
|
74
|
+
#elif defined(__APPLE__)
|
|
75
|
+
ret = mach_thread_self();
|
|
76
|
+
mach_port_deallocate(mach_task_self(), ret);
|
|
77
|
+
#elif defined(__CYGWIN__)
|
|
78
|
+
ret = GetCurrentThreadId();
|
|
79
|
+
#endif
|
|
80
|
+
/* TODO: NetBSD thread ID support */
|
|
81
|
+
return ret;
|
|
82
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* libusb synchronization using POSIX Threads
|
|
3
|
+
*
|
|
4
|
+
* Copyright © 2010 Peter Stuge <peter@stuge.se>
|
|
5
|
+
*
|
|
6
|
+
* This library is free software; you can redistribute it and/or
|
|
7
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
8
|
+
* License as published by the Free Software Foundation; either
|
|
9
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
10
|
+
*
|
|
11
|
+
* This library is distributed in the hope that it will be useful,
|
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
14
|
+
* Lesser General Public License for more details.
|
|
15
|
+
*
|
|
16
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
17
|
+
* License along with this library; if not, write to the Free Software
|
|
18
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
#ifndef LIBUSB_THREADS_POSIX_H
|
|
22
|
+
#define LIBUSB_THREADS_POSIX_H
|
|
23
|
+
|
|
24
|
+
#include <pthread.h>
|
|
25
|
+
|
|
26
|
+
#define usbi_mutex_static_t pthread_mutex_t
|
|
27
|
+
#define USBI_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
|
28
|
+
#define usbi_mutex_static_lock pthread_mutex_lock
|
|
29
|
+
#define usbi_mutex_static_unlock pthread_mutex_unlock
|
|
30
|
+
|
|
31
|
+
#define usbi_mutex_t pthread_mutex_t
|
|
32
|
+
#define usbi_mutex_init pthread_mutex_init
|
|
33
|
+
#define usbi_mutex_lock pthread_mutex_lock
|
|
34
|
+
#define usbi_mutex_unlock pthread_mutex_unlock
|
|
35
|
+
#define usbi_mutex_trylock pthread_mutex_trylock
|
|
36
|
+
#define usbi_mutex_destroy pthread_mutex_destroy
|
|
37
|
+
|
|
38
|
+
#define usbi_cond_t pthread_cond_t
|
|
39
|
+
#define usbi_cond_init pthread_cond_init
|
|
40
|
+
#define usbi_cond_wait pthread_cond_wait
|
|
41
|
+
#define usbi_cond_timedwait pthread_cond_timedwait
|
|
42
|
+
#define usbi_cond_broadcast pthread_cond_broadcast
|
|
43
|
+
#define usbi_cond_destroy pthread_cond_destroy
|
|
44
|
+
#define usbi_cond_signal pthread_cond_signal
|
|
45
|
+
|
|
46
|
+
extern int usbi_mutex_init_recursive(pthread_mutex_t *mutex, pthread_mutexattr_t *attr);
|
|
47
|
+
|
|
48
|
+
int usbi_get_tid(void);
|
|
49
|
+
|
|
50
|
+
#endif /* LIBUSB_THREADS_POSIX_H */
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* libusb synchronization on Microsoft Windows
|
|
3
|
+
*
|
|
4
|
+
* Copyright © 2010 Michael Plante <michael.plante@gmail.com>
|
|
5
|
+
*
|
|
6
|
+
* This library is free software; you can redistribute it and/or
|
|
7
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
8
|
+
* License as published by the Free Software Foundation; either
|
|
9
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
10
|
+
*
|
|
11
|
+
* This library is distributed in the hope that it will be useful,
|
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
14
|
+
* Lesser General Public License for more details.
|
|
15
|
+
*
|
|
16
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
17
|
+
* License along with this library; if not, write to the Free Software
|
|
18
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
#include <config.h>
|
|
22
|
+
#include <objbase.h>
|
|
23
|
+
#include <errno.h>
|
|
24
|
+
#include <stdarg.h>
|
|
25
|
+
|
|
26
|
+
#include "libusbi.h"
|
|
27
|
+
|
|
28
|
+
extern const uint64_t epoch_time;
|
|
29
|
+
|
|
30
|
+
int usbi_mutex_init(usbi_mutex_t *mutex,
|
|
31
|
+
const usbi_mutexattr_t *attr) {
|
|
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
|
+
}
|
|
70
|
+
|
|
71
|
+
int usbi_mutex_static_lock(usbi_mutex_static_t *mutex) {
|
|
72
|
+
if(!mutex) return ((errno=EINVAL));
|
|
73
|
+
while (InterlockedExchange((LONG *)mutex, 1) == 1) {
|
|
74
|
+
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
|
+
}
|
|
83
|
+
|
|
84
|
+
int usbi_cond_init(usbi_cond_t *cond,
|
|
85
|
+
const usbi_condattr_t *attr) {
|
|
86
|
+
UNUSED(attr);
|
|
87
|
+
if(!cond) return ((errno=EINVAL));
|
|
88
|
+
list_init(&cond->waiters );
|
|
89
|
+
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
|
+
}
|
|
105
|
+
|
|
106
|
+
int usbi_cond_broadcast(usbi_cond_t *cond) {
|
|
107
|
+
// Assumes mutex is locked; this is not in keeping with POSIX spec, but
|
|
108
|
+
// libusb does this anyway, so we simplify by not adding more sync
|
|
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!
|
|
124
|
+
struct usbi_cond_perthread *pos;
|
|
125
|
+
if(!cond) return ((errno=EINVAL));
|
|
126
|
+
if(list_empty(&cond->waiters)) return 0; // no one to wakeup.
|
|
127
|
+
pos = list_entry(&cond->waiters.next, struct usbi_cond_perthread, list);
|
|
128
|
+
// The wait function will remove its respective item from the list.
|
|
129
|
+
return SetEvent(pos->event) ? 0 : ((errno=EINVAL));
|
|
130
|
+
}
|
|
131
|
+
__inline static int usbi_cond_intwait(usbi_cond_t *cond,
|
|
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;
|
|
148
|
+
pos->event = CreateEvent(NULL, FALSE, FALSE, NULL); // auto-reset.
|
|
149
|
+
if(!pos->event) {
|
|
150
|
+
free(pos);
|
|
151
|
+
return ((errno=ENOMEM));
|
|
152
|
+
}
|
|
153
|
+
list_add(&pos->list, &cond->not_waiting);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
list_del(&pos->list); // remove from not_waiting list.
|
|
157
|
+
list_add(&pos->list, &cond->waiters);
|
|
158
|
+
|
|
159
|
+
r = usbi_mutex_unlock(mutex);
|
|
160
|
+
if(r) return r;
|
|
161
|
+
r2 = WaitForSingleObject(pos->event, timeout_ms);
|
|
162
|
+
r = usbi_mutex_lock(mutex);
|
|
163
|
+
if(r) return r;
|
|
164
|
+
|
|
165
|
+
list_del(&pos->list);
|
|
166
|
+
list_add(&pos->list, &cond->not_waiting);
|
|
167
|
+
|
|
168
|
+
if(r2 == WAIT_TIMEOUT) return ((errno=ETIMEDOUT));
|
|
169
|
+
|
|
170
|
+
return 0;
|
|
171
|
+
}
|
|
172
|
+
// 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) {
|
|
174
|
+
return usbi_cond_intwait(cond, mutex, INFINITE);
|
|
175
|
+
}
|
|
176
|
+
int usbi_cond_timedwait(usbi_cond_t *cond,
|
|
177
|
+
usbi_mutex_t *mutex,
|
|
178
|
+
const struct timespec *abstime) {
|
|
179
|
+
FILETIME filetime;
|
|
180
|
+
ULARGE_INTEGER rtime;
|
|
181
|
+
struct timeval targ_time, cur_time, delta_time;
|
|
182
|
+
struct timespec cur_time_ns;
|
|
183
|
+
DWORD millis;
|
|
184
|
+
|
|
185
|
+
// GetSystemTimeAsFileTime() is not available on CE
|
|
186
|
+
SYSTEMTIME st;
|
|
187
|
+
GetSystemTime(&st);
|
|
188
|
+
SystemTimeToFileTime(&st, &filetime);
|
|
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
|
+
|
|
207
|
+
return usbi_cond_intwait(cond, mutex, millis);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
int usbi_get_tid(void) {
|
|
211
|
+
return GetCurrentThreadId();
|
|
212
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* libusb synchronization on Microsoft Windows
|
|
3
|
+
*
|
|
4
|
+
* Copyright © 2010 Michael Plante <michael.plante@gmail.com>
|
|
5
|
+
*
|
|
6
|
+
* This library is free software; you can redistribute it and/or
|
|
7
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
8
|
+
* License as published by the Free Software Foundation; either
|
|
9
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
10
|
+
*
|
|
11
|
+
* This library is distributed in the hope that it will be useful,
|
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
14
|
+
* Lesser General Public License for more details.
|
|
15
|
+
*
|
|
16
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
17
|
+
* License along with this library; if not, write to the Free Software
|
|
18
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
#ifndef LIBUSB_THREADS_WINDOWS_H
|
|
22
|
+
#define LIBUSB_THREADS_WINDOWS_H
|
|
23
|
+
|
|
24
|
+
#define usbi_mutex_static_t volatile LONG
|
|
25
|
+
#define USBI_MUTEX_INITIALIZER 0
|
|
26
|
+
|
|
27
|
+
#define usbi_mutex_t HANDLE
|
|
28
|
+
|
|
29
|
+
struct usbi_cond_perthread {
|
|
30
|
+
struct list_head list;
|
|
31
|
+
DWORD tid;
|
|
32
|
+
HANDLE event;
|
|
33
|
+
};
|
|
34
|
+
struct usbi_cond_t_ {
|
|
35
|
+
// Every time a thread touches the CV, it winds up in one of these lists.
|
|
36
|
+
// It stays there until the CV is destroyed, even if the thread
|
|
37
|
+
// terminates.
|
|
38
|
+
struct list_head waiters;
|
|
39
|
+
struct list_head not_waiting;
|
|
40
|
+
};
|
|
41
|
+
typedef struct usbi_cond_t_ usbi_cond_t;
|
|
42
|
+
|
|
43
|
+
// We *were* getting timespec from pthread.h:
|
|
44
|
+
#if (!defined(HAVE_STRUCT_TIMESPEC) && !defined(_TIMESPEC_DEFINED))
|
|
45
|
+
#define HAVE_STRUCT_TIMESPEC 1
|
|
46
|
+
#define _TIMESPEC_DEFINED 1
|
|
47
|
+
struct timespec {
|
|
48
|
+
long tv_sec;
|
|
49
|
+
long tv_nsec;
|
|
50
|
+
};
|
|
51
|
+
#endif /* HAVE_STRUCT_TIMESPEC | _TIMESPEC_DEFINED */
|
|
52
|
+
|
|
53
|
+
// We *were* getting ETIMEDOUT from pthread.h:
|
|
54
|
+
#ifndef ETIMEDOUT
|
|
55
|
+
# define ETIMEDOUT 10060 /* This is the value in winsock.h. */
|
|
56
|
+
#endif
|
|
57
|
+
|
|
58
|
+
#define usbi_mutexattr_t void
|
|
59
|
+
#define usbi_condattr_t void
|
|
60
|
+
|
|
61
|
+
// all Windows mutexes are recursive
|
|
62
|
+
#define usbi_mutex_init_recursive(mutex, attr) usbi_mutex_init((mutex), (attr))
|
|
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
|
+
|
|
75
|
+
int usbi_cond_init(usbi_cond_t *cond,
|
|
76
|
+
const usbi_condattr_t *attr);
|
|
77
|
+
int usbi_cond_destroy(usbi_cond_t *cond);
|
|
78
|
+
int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex);
|
|
79
|
+
int usbi_cond_timedwait(usbi_cond_t *cond,
|
|
80
|
+
usbi_mutex_t *mutex,
|
|
81
|
+
const struct timespec *abstime);
|
|
82
|
+
int usbi_cond_broadcast(usbi_cond_t *cond);
|
|
83
|
+
int usbi_cond_signal(usbi_cond_t *cond);
|
|
84
|
+
|
|
85
|
+
int usbi_get_tid(void);
|
|
86
|
+
|
|
87
|
+
#endif /* LIBUSB_THREADS_WINDOWS_H */
|