libusb 0.3.4 → 0.4.0
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Gemfile +1 -0
- data/History.md +10 -0
- data/README.md +19 -6
- data/Rakefile +1 -1
- data/ext/extconf.rb +17 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/AUTHORS +18 -6
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/COPYING +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ChangeLog +58 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/INSTALL +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.am +6 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.in +248 -174
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/NEWS +2 -2
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/PORTING +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/README +2 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/TODO +0 -0
- data/ext/libusbx-1.0.17/Xcode/common.xcconfig +40 -0
- data/ext/libusbx-1.0.17/Xcode/config.h +28 -0
- data/ext/libusbx-1.0.17/Xcode/debug.xcconfig +29 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx.xcconfig +21 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx.xcodeproj/project.pbxproj +864 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx_debug.xcconfig +21 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx_release.xcconfig +21 -0
- data/ext/libusbx-1.0.17/Xcode/release.xcconfig +29 -0
- data/ext/libusbx-1.0.17/aclocal.m4 +1112 -0
- data/ext/libusbx-1.0.17/android/README +114 -0
- data/ext/libusbx-1.0.17/android/config.h +90 -0
- data/ext/libusbx-1.0.17/android/jni/Android.mk +23 -0
- data/ext/libusbx-1.0.17/android/jni/Application.mk +19 -0
- data/ext/libusbx-1.0.17/android/jni/examples.mk +134 -0
- data/ext/libusbx-1.0.17/android/jni/libusb.mk +54 -0
- data/ext/libusbx-1.0.17/android/jni/tests.mk +56 -0
- data/ext/libusbx-1.0.17/compile +347 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.guess +164 -130
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.h.in +37 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.sub +174 -89
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure +723 -302
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure.ac +71 -20
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/depcomp +345 -185
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.am +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.in +95 -32
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/doxygen.cfg.in +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.am +5 -4
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.in +208 -104
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp.c +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp_threaded.c +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.c +188 -8
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.h +18 -5
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/fxload.c +90 -64
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.c +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.h +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt1.c +0 -0
- data/ext/libusbx-1.0.17/examples/hotplugtest.c +97 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/listdevs.c +12 -4
- data/ext/libusbx-1.0.17/examples/sam3u_benchmark.c +193 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/xusb.c +106 -49
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/install-sh +21 -14
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb-1.0.pc.in +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/Makefile.am +29 -10
- data/ext/libusbx-1.0.17/libusb/Makefile.in +914 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/core.c +378 -87
- data/ext/libusbx-1.0.17/libusb/descriptor.c +1199 -0
- data/ext/libusbx-1.0.17/libusb/hotplug.c +322 -0
- data/ext/libusbx-1.0.17/libusb/hotplug.h +82 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/io.c +182 -62
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.def +32 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.rc +2 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb.h +481 -32
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusbi.h +135 -38
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.c +591 -496
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.h +39 -46
- data/ext/libusbx-1.0.17/libusb/os/linux_netlink.c +345 -0
- data/ext/libusbx-1.0.17/libusb/os/linux_udev.c +306 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.c +653 -617
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.h +32 -0
- data/ext/{libusbx-1.0.14/libusb/os/openbsd_usb.c → libusbx-1.0.17/libusb/os/netbsd_usb.c} +70 -63
- data/ext/libusbx-1.0.17/libusb/os/openbsd_usb.c +823 -0
- data/ext/libusbx-1.0.17/libusb/os/poll_posix.c +51 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_posix.h +2 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.c +85 -106
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.h +14 -3
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.c +3 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.h +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.c +6 -5
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.h +0 -0
- data/ext/libusbx-1.0.17/libusb/os/wince_usb.c +1026 -0
- data/ext/libusbx-1.0.17/libusb/os/wince_usb.h +131 -0
- data/ext/libusbx-1.0.17/libusb/os/windows_common.h +108 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.c +92 -57
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.h +2 -63
- data/ext/libusbx-1.0.17/libusb/strerror.c +184 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/sync.c +24 -38
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/version.h +1 -1
- data/ext/libusbx-1.0.17/libusb/version_nano.h +1 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ltmain.sh +60 -41
- data/ext/{libusbx-1.0.14/aclocal.m4 → libusbx-1.0.17/m4/libtool.m4} +229 -1723
- data/ext/libusbx-1.0.17/m4/ltoptions.m4 +384 -0
- data/ext/libusbx-1.0.17/m4/ltsugar.m4 +123 -0
- data/ext/libusbx-1.0.17/m4/ltversion.m4 +23 -0
- data/ext/libusbx-1.0.17/m4/lt~obsolete.m4 +98 -0
- data/ext/libusbx-1.0.17/missing +215 -0
- data/ext/libusbx-1.0.17/tests/Makefile.am +6 -0
- data/ext/libusbx-1.0.17/tests/Makefile.in +583 -0
- data/ext/libusbx-1.0.17/tests/libusbx_testlib.h +107 -0
- data/ext/libusbx-1.0.17/tests/stress.c +160 -0
- data/ext/libusbx-1.0.17/tests/testlib.c +276 -0
- data/lib/libusb.rb +4 -0
- data/lib/libusb/call.rb +43 -1
- data/lib/libusb/constants.rb +5 -0
- data/lib/libusb/context.rb +100 -0
- data/lib/libusb/dev_handle.rb +27 -0
- data/lib/libusb/device.rb +10 -4
- data/lib/libusb/version_gem.rb +1 -1
- data/test/test_libusb_capability.rb +2 -2
- data/test/test_libusb_compat.rb +2 -2
- data/test/test_libusb_compat_mass_storage.rb +2 -2
- data/test/test_libusb_descriptors.rb +4 -2
- data/test/test_libusb_event_machine.rb +2 -2
- data/test/test_libusb_gc.rb +2 -2
- data/test/test_libusb_hotplug.rb +115 -0
- data/test/test_libusb_iso_transfer.rb +3 -3
- data/test/test_libusb_mass_storage.rb +6 -16
- data/test/test_libusb_mass_storage2.rb +26 -3
- data/test/test_libusb_structs.rb +2 -2
- data/test/test_libusb_threads.rb +2 -2
- data/test/test_libusb_version.rb +2 -2
- metadata +127 -68
- metadata.gz.sig +0 -0
- data/ext/libusbx-1.0.14/THANKS +0 -7
- data/ext/libusbx-1.0.14/compile +0 -143
- data/ext/libusbx-1.0.14/libusb/Makefile.in +0 -721
- data/ext/libusbx-1.0.14/libusb/descriptor.c +0 -731
- data/ext/libusbx-1.0.14/libusb/version_nano.h +0 -1
- data/ext/libusbx-1.0.14/missing +0 -376
@@ -0,0 +1,51 @@
|
|
1
|
+
/*
|
2
|
+
* poll_posix: poll compatibility wrapper for POSIX systems
|
3
|
+
* Copyright © 2013 RealVNC Ltd.
|
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
|
+
|
21
|
+
#include <unistd.h>
|
22
|
+
#include <fcntl.h>
|
23
|
+
#include <errno.h>
|
24
|
+
#include <stdlib.h>
|
25
|
+
|
26
|
+
#include "libusbi.h"
|
27
|
+
|
28
|
+
int usbi_pipe(int pipefd[2])
|
29
|
+
{
|
30
|
+
int ret = pipe(pipefd);
|
31
|
+
if (ret != 0) {
|
32
|
+
return ret;
|
33
|
+
}
|
34
|
+
ret = fcntl(pipefd[1], F_GETFL);
|
35
|
+
if (ret == -1) {
|
36
|
+
usbi_dbg("Failed to get pipe fd flags: %d", errno);
|
37
|
+
goto err_close_pipe;
|
38
|
+
}
|
39
|
+
ret = fcntl(pipefd[1], F_SETFL, ret | O_NONBLOCK);
|
40
|
+
if (ret != 0) {
|
41
|
+
usbi_dbg("Failed to set non-blocking on new pipe: %d", errno);
|
42
|
+
goto err_close_pipe;
|
43
|
+
}
|
44
|
+
|
45
|
+
return 0;
|
46
|
+
|
47
|
+
err_close_pipe:
|
48
|
+
usbi_close(pipefd[0]);
|
49
|
+
usbi_close(pipefd[1]);
|
50
|
+
return ret;
|
51
|
+
}
|
@@ -1,6 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* poll_windows: poll compatibility wrapper for Windows
|
3
|
-
* Copyright ©
|
3
|
+
* Copyright © 2012-2013 RealVNC Ltd.
|
4
|
+
* Copyright © 2009-2010 Pete Batard <pete@akeo.ie>
|
4
5
|
* With contributions from Michael Plante, Orin Eman et al.
|
5
6
|
* Parts of poll implementation from libusb-win32, by Stephan Meyer et al.
|
6
7
|
*
|
@@ -31,7 +32,7 @@
|
|
31
32
|
* OVERLAPPED mode
|
32
33
|
* - call usbi_create_fd with this handle to obtain a custom fd.
|
33
34
|
* Note that if you need simultaneous R/W access, you need to call create_fd
|
34
|
-
* twice, once in
|
35
|
+
* twice, once in RW_READ and once in RW_WRITE mode to obtain 2 separate
|
35
36
|
* pollable fds
|
36
37
|
* - leave the core functions call the poll routine and flag POLLIN/POLLOUT
|
37
38
|
*
|
@@ -40,12 +41,10 @@
|
|
40
41
|
* context.
|
41
42
|
*/
|
42
43
|
#include <errno.h>
|
43
|
-
#include <fcntl.h>
|
44
44
|
#include <stdio.h>
|
45
45
|
#include <stdlib.h>
|
46
|
-
#include <io.h>
|
47
46
|
|
48
|
-
#include
|
47
|
+
#include "libusbi.h"
|
49
48
|
|
50
49
|
// Uncomment to debug the polling layer
|
51
50
|
//#define DEBUG_POLL_WINDOWS
|
@@ -54,7 +53,7 @@
|
|
54
53
|
#else
|
55
54
|
// MSVC++ < 2005 cannot use a variadic argument and non MSVC
|
56
55
|
// compilers produce warnings if parenthesis are ommitted.
|
57
|
-
#if defined(_MSC_VER) && _MSC_VER < 1400
|
56
|
+
#if defined(_MSC_VER) && (_MSC_VER < 1400)
|
58
57
|
#define poll_dbg
|
59
58
|
#else
|
60
59
|
#define poll_dbg(...)
|
@@ -65,20 +64,10 @@
|
|
65
64
|
#pragma warning(disable:28719)
|
66
65
|
#endif
|
67
66
|
|
68
|
-
#if defined(__CYGWIN__)
|
69
|
-
// cygwin produces a warning unless these prototypes are defined
|
70
|
-
extern int _open(char* name, int flags);
|
71
|
-
extern int _close(int fd);
|
72
|
-
extern int _snprintf(char *buffer, size_t count, const char *format, ...);
|
73
|
-
#define NUL_DEVICE "/dev/null"
|
74
|
-
#else
|
75
|
-
#define NUL_DEVICE "NUL"
|
76
|
-
#endif
|
77
|
-
|
78
67
|
#define CHECK_INIT_POLLING do {if(!is_polling_set) init_polling();} while(0)
|
79
68
|
|
80
69
|
// public fd data
|
81
|
-
const struct winfd INVALID_WINFD = {-1, INVALID_HANDLE_VALUE, NULL, RW_NONE};
|
70
|
+
const struct winfd INVALID_WINFD = {-1, INVALID_HANDLE_VALUE, NULL, NULL, NULL, RW_NONE};
|
82
71
|
struct winfd poll_fd[MAX_FDS];
|
83
72
|
// internal fd data
|
84
73
|
struct {
|
@@ -93,12 +82,25 @@ BOOLEAN is_polling_set = FALSE;
|
|
93
82
|
LONG pipe_number = 0;
|
94
83
|
static volatile LONG compat_spinlock = 0;
|
95
84
|
|
85
|
+
#if !defined(_WIN32_WCE)
|
96
86
|
// CancelIoEx, available on Vista and later only, provides the ability to cancel
|
97
87
|
// a single transfer (OVERLAPPED) when used. As it may not be part of any of the
|
98
88
|
// platform headers, we hook into the Kernel32 system DLL directly to seek it.
|
99
89
|
static BOOL (__stdcall *pCancelIoEx)(HANDLE, LPOVERLAPPED) = NULL;
|
100
|
-
#define
|
101
|
-
|
90
|
+
#define Use_Duplicate_Handles (pCancelIoEx == NULL)
|
91
|
+
|
92
|
+
static inline void setup_cancel_io(void)
|
93
|
+
{
|
94
|
+
HMODULE hKernel32 = GetModuleHandleA("KERNEL32");
|
95
|
+
if (hKernel32 != NULL) {
|
96
|
+
pCancelIoEx = (BOOL (__stdcall *)(HANDLE,LPOVERLAPPED))
|
97
|
+
GetProcAddress(hKernel32, "CancelIoEx");
|
98
|
+
}
|
99
|
+
usbi_dbg("Will use CancelIo%s for I/O cancellation",
|
100
|
+
Use_Duplicate_Handles?"":"Ex");
|
101
|
+
}
|
102
|
+
|
103
|
+
static inline BOOL cancel_io(int _index)
|
102
104
|
{
|
103
105
|
if ((_index < 0) || (_index >= MAX_FDS)) {
|
104
106
|
return FALSE;
|
@@ -108,7 +110,12 @@ static __inline BOOL cancel_io(int _index)
|
|
108
110
|
|| (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL) ) {
|
109
111
|
return TRUE;
|
110
112
|
}
|
111
|
-
if (
|
113
|
+
if (poll_fd[_index].itransfer && poll_fd[_index].cancel_fn) {
|
114
|
+
// Cancel outstanding transfer via the specific callback
|
115
|
+
(*poll_fd[_index].cancel_fn)(poll_fd[_index].itransfer);
|
116
|
+
return TRUE;
|
117
|
+
}
|
118
|
+
if (pCancelIoEx != NULL) {
|
112
119
|
return (*pCancelIoEx)(poll_fd[_index].handle, poll_fd[_index].overlapped);
|
113
120
|
}
|
114
121
|
if (_poll_fd[_index].thread_id == GetCurrentThreadId()) {
|
@@ -117,6 +124,30 @@ static __inline BOOL cancel_io(int _index)
|
|
117
124
|
usbi_warn(NULL, "Unable to cancel I/O that was started from another thread");
|
118
125
|
return FALSE;
|
119
126
|
}
|
127
|
+
#else
|
128
|
+
#define Use_Duplicate_Handles FALSE
|
129
|
+
|
130
|
+
static __inline void setup_cancel_io()
|
131
|
+
{
|
132
|
+
// No setup needed on WinCE
|
133
|
+
}
|
134
|
+
|
135
|
+
static __inline BOOL cancel_io(int _index)
|
136
|
+
{
|
137
|
+
if ((_index < 0) || (_index >= MAX_FDS)) {
|
138
|
+
return FALSE;
|
139
|
+
}
|
140
|
+
if ( (poll_fd[_index].fd < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
|
141
|
+
|| (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL) ) {
|
142
|
+
return TRUE;
|
143
|
+
}
|
144
|
+
if (poll_fd[_index].itransfer && poll_fd[_index].cancel_fn) {
|
145
|
+
// Cancel outstanding transfer via the specific callback
|
146
|
+
(*poll_fd[_index].cancel_fn)(poll_fd[_index].itransfer);
|
147
|
+
}
|
148
|
+
return TRUE;
|
149
|
+
}
|
150
|
+
#endif
|
120
151
|
|
121
152
|
// Init
|
122
153
|
void init_polling(void)
|
@@ -127,10 +158,7 @@ void init_polling(void)
|
|
127
158
|
SleepEx(0, TRUE);
|
128
159
|
}
|
129
160
|
if (!is_polling_set) {
|
130
|
-
|
131
|
-
GetProcAddress(GetModuleHandleA("KERNEL32"), "CancelIoEx");
|
132
|
-
usbi_dbg("Will use CancelIo%s for I/O cancellation",
|
133
|
-
CancelIoEx_Available?"Ex":"");
|
161
|
+
setup_cancel_io();
|
134
162
|
for (i=0; i<MAX_FDS; i++) {
|
135
163
|
poll_fd[i] = INVALID_WINFD;
|
136
164
|
_poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
|
@@ -143,11 +171,11 @@ void init_polling(void)
|
|
143
171
|
}
|
144
172
|
|
145
173
|
// Internal function to retrieve the table index (and lock the fd mutex)
|
146
|
-
int _fd_to_index_and_lock(int fd)
|
174
|
+
static int _fd_to_index_and_lock(int fd)
|
147
175
|
{
|
148
176
|
int i;
|
149
177
|
|
150
|
-
if (fd
|
178
|
+
if (fd < 0)
|
151
179
|
return -1;
|
152
180
|
|
153
181
|
for (i=0; i<MAX_FDS; i++) {
|
@@ -164,7 +192,7 @@ int _fd_to_index_and_lock(int fd)
|
|
164
192
|
return -1;
|
165
193
|
}
|
166
194
|
|
167
|
-
OVERLAPPED *create_overlapped(void)
|
195
|
+
static OVERLAPPED *create_overlapped(void)
|
168
196
|
{
|
169
197
|
OVERLAPPED *overlapped = (OVERLAPPED*) calloc(1, sizeof(OVERLAPPED));
|
170
198
|
if (overlapped == NULL) {
|
@@ -178,7 +206,7 @@ OVERLAPPED *create_overlapped(void)
|
|
178
206
|
return overlapped;
|
179
207
|
}
|
180
208
|
|
181
|
-
void free_overlapped(OVERLAPPED *overlapped)
|
209
|
+
static void free_overlapped(OVERLAPPED *overlapped)
|
182
210
|
{
|
183
211
|
if (overlapped == NULL)
|
184
212
|
return;
|
@@ -190,20 +218,6 @@ void free_overlapped(OVERLAPPED *overlapped)
|
|
190
218
|
free(overlapped);
|
191
219
|
}
|
192
220
|
|
193
|
-
void reset_overlapped(OVERLAPPED *overlapped)
|
194
|
-
{
|
195
|
-
HANDLE event_handle;
|
196
|
-
if (overlapped == NULL)
|
197
|
-
return;
|
198
|
-
|
199
|
-
event_handle = overlapped->hEvent;
|
200
|
-
if (event_handle != NULL) {
|
201
|
-
ResetEvent(event_handle);
|
202
|
-
}
|
203
|
-
memset(overlapped, 0, sizeof(OVERLAPPED));
|
204
|
-
overlapped->hEvent = event_handle;
|
205
|
-
}
|
206
|
-
|
207
221
|
void exit_polling(void)
|
208
222
|
{
|
209
223
|
int i;
|
@@ -221,12 +235,8 @@ void exit_polling(void)
|
|
221
235
|
// terminating, and we should be able to access the fd
|
222
236
|
// mutex lock before too long
|
223
237
|
EnterCriticalSection(&_poll_fd[i].mutex);
|
224
|
-
if ( (poll_fd[i].fd > 0) && (poll_fd[i].handle != INVALID_HANDLE_VALUE) && (poll_fd[i].handle != 0)
|
225
|
-
&& (GetFileType(poll_fd[i].handle) == FILE_TYPE_UNKNOWN) ) {
|
226
|
-
_close(poll_fd[i].fd);
|
227
|
-
}
|
228
238
|
free_overlapped(poll_fd[i].overlapped);
|
229
|
-
if (
|
239
|
+
if (Use_Duplicate_Handles) {
|
230
240
|
// Close duplicate handle
|
231
241
|
if (_poll_fd[i].original_handle != INVALID_HANDLE_VALUE) {
|
232
242
|
CloseHandle(poll_fd[i].handle);
|
@@ -253,7 +263,8 @@ int usbi_pipe(int filedes[2])
|
|
253
263
|
|
254
264
|
CHECK_INIT_POLLING;
|
255
265
|
|
256
|
-
overlapped = (
|
266
|
+
overlapped = create_overlapped();
|
267
|
+
|
257
268
|
if (overlapped == NULL) {
|
258
269
|
return -1;
|
259
270
|
}
|
@@ -261,22 +272,6 @@ int usbi_pipe(int filedes[2])
|
|
261
272
|
overlapped->Internal = STATUS_PENDING;
|
262
273
|
overlapped->InternalHigh = 0;
|
263
274
|
|
264
|
-
// Read end of the "pipe"
|
265
|
-
filedes[0] = _open(NUL_DEVICE, _O_WRONLY);
|
266
|
-
if (filedes[0] < 0) {
|
267
|
-
usbi_err(NULL, "could not create pipe: errno %d", errno);
|
268
|
-
goto out1;
|
269
|
-
}
|
270
|
-
// We can use the same handle for both ends
|
271
|
-
filedes[1] = filedes[0];
|
272
|
-
poll_dbg("pipe filedes = %d", filedes[0]);
|
273
|
-
|
274
|
-
// Note: manual reset must be true (second param) as the reset occurs in read
|
275
|
-
overlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
276
|
-
if(!overlapped->hEvent) {
|
277
|
-
goto out2;
|
278
|
-
}
|
279
|
-
|
280
275
|
for (i=0; i<MAX_FDS; i++) {
|
281
276
|
if (poll_fd[i].fd < 0) {
|
282
277
|
EnterCriticalSection(&_poll_fd[i].mutex);
|
@@ -286,7 +281,13 @@ int usbi_pipe(int filedes[2])
|
|
286
281
|
continue;
|
287
282
|
}
|
288
283
|
|
289
|
-
|
284
|
+
// Use index as the unique fd number
|
285
|
+
poll_fd[i].fd = i;
|
286
|
+
// Read end of the "pipe"
|
287
|
+
filedes[0] = poll_fd[i].fd;
|
288
|
+
// We can use the same handle for both ends
|
289
|
+
filedes[1] = filedes[0];
|
290
|
+
|
290
291
|
poll_fd[i].handle = DUMMY_HANDLE;
|
291
292
|
poll_fd[i].overlapped = overlapped;
|
292
293
|
// There's no polling on the write end, so we just use READ for our needs
|
@@ -296,12 +297,7 @@ int usbi_pipe(int filedes[2])
|
|
296
297
|
return 0;
|
297
298
|
}
|
298
299
|
}
|
299
|
-
|
300
|
-
CloseHandle(overlapped->hEvent);
|
301
|
-
out2:
|
302
|
-
_close(filedes[0]);
|
303
|
-
out1:
|
304
|
-
free(overlapped);
|
300
|
+
free_overlapped(overlapped);
|
305
301
|
return -1;
|
306
302
|
}
|
307
303
|
|
@@ -319,9 +315,9 @@ out1:
|
|
319
315
|
* read and one for write. Using a single R/W fd is unsupported and will
|
320
316
|
* produce unexpected results
|
321
317
|
*/
|
322
|
-
struct winfd usbi_create_fd(HANDLE handle, int access_mode)
|
318
|
+
struct winfd usbi_create_fd(HANDLE handle, int access_mode, struct usbi_transfer *itransfer, cancel_transfer *cancel_fn)
|
323
319
|
{
|
324
|
-
int i
|
320
|
+
int i;
|
325
321
|
struct winfd wfd = INVALID_WINFD;
|
326
322
|
OVERLAPPED* overlapped = NULL;
|
327
323
|
|
@@ -331,27 +327,22 @@ struct winfd usbi_create_fd(HANDLE handle, int access_mode)
|
|
331
327
|
return INVALID_WINFD;
|
332
328
|
}
|
333
329
|
|
334
|
-
|
335
|
-
|
330
|
+
wfd.itransfer = itransfer;
|
331
|
+
wfd.cancel_fn = cancel_fn;
|
332
|
+
|
333
|
+
if ((access_mode != RW_READ) && (access_mode != RW_WRITE)) {
|
334
|
+
usbi_warn(NULL, "only one of RW_READ or RW_WRITE are supported.\n"
|
336
335
|
"If you want to poll for R/W simultaneously, create multiple fds from the same handle.");
|
337
336
|
return INVALID_WINFD;
|
338
337
|
}
|
339
|
-
if (access_mode ==
|
338
|
+
if (access_mode == RW_READ) {
|
340
339
|
wfd.rw = RW_READ;
|
341
340
|
} else {
|
342
341
|
wfd.rw = RW_WRITE;
|
343
342
|
}
|
344
343
|
|
345
|
-
// Ensure that we get a non system conflicting unique fd, using
|
346
|
-
// the same fd attribution system as the pipe ends
|
347
|
-
fd = _open(NUL_DEVICE, _O_WRONLY);
|
348
|
-
if (fd < 0) {
|
349
|
-
return INVALID_WINFD;
|
350
|
-
}
|
351
|
-
|
352
344
|
overlapped = create_overlapped();
|
353
345
|
if(overlapped == NULL) {
|
354
|
-
_close(fd);
|
355
346
|
return INVALID_WINFD;
|
356
347
|
}
|
357
348
|
|
@@ -363,10 +354,11 @@ struct winfd usbi_create_fd(HANDLE handle, int access_mode)
|
|
363
354
|
LeaveCriticalSection(&_poll_fd[i].mutex);
|
364
355
|
continue;
|
365
356
|
}
|
366
|
-
|
357
|
+
// Use index as the unique fd number
|
358
|
+
wfd.fd = i;
|
367
359
|
// Attempt to emulate some of the CancelIoEx behaviour on platforms
|
368
360
|
// that don't have it
|
369
|
-
if (
|
361
|
+
if (Use_Duplicate_Handles) {
|
370
362
|
_poll_fd[i].thread_id = GetCurrentThreadId();
|
371
363
|
if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(),
|
372
364
|
&wfd.handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
|
@@ -387,21 +379,15 @@ struct winfd usbi_create_fd(HANDLE handle, int access_mode)
|
|
387
379
|
}
|
388
380
|
}
|
389
381
|
free_overlapped(overlapped);
|
390
|
-
_close(fd);
|
391
382
|
return INVALID_WINFD;
|
392
383
|
}
|
393
384
|
|
394
|
-
void _free_index(int _index)
|
385
|
+
static void _free_index(int _index)
|
395
386
|
{
|
396
387
|
// Cancel any async IO (Don't care about the validity of our handles for this)
|
397
388
|
cancel_io(_index);
|
398
|
-
// close fake handle for devices
|
399
|
-
if ( (poll_fd[_index].handle != INVALID_HANDLE_VALUE) && (poll_fd[_index].handle != 0)
|
400
|
-
&& (GetFileType(poll_fd[_index].handle) == FILE_TYPE_UNKNOWN) ) {
|
401
|
-
_close(poll_fd[_index].fd);
|
402
|
-
}
|
403
389
|
// close the duplicate handle (if we have an actual duplicate)
|
404
|
-
if (
|
390
|
+
if (Use_Duplicate_Handles) {
|
405
391
|
if (_poll_fd[_index].original_handle != INVALID_HANDLE_VALUE) {
|
406
392
|
CloseHandle(poll_fd[_index].handle);
|
407
393
|
}
|
@@ -417,17 +403,18 @@ void _free_index(int _index)
|
|
417
403
|
*
|
418
404
|
* Note that the associated Windows handle is not closed by this call
|
419
405
|
*/
|
420
|
-
void usbi_free_fd(
|
406
|
+
void usbi_free_fd(struct winfd *wfd)
|
421
407
|
{
|
422
408
|
int _index;
|
423
409
|
|
424
410
|
CHECK_INIT_POLLING;
|
425
411
|
|
426
|
-
_index = _fd_to_index_and_lock(fd);
|
412
|
+
_index = _fd_to_index_and_lock(wfd->fd);
|
427
413
|
if (_index < 0) {
|
428
414
|
return;
|
429
415
|
}
|
430
416
|
_free_index(_index);
|
417
|
+
*wfd = INVALID_WINFD;
|
431
418
|
LeaveCriticalSection(&_poll_fd[_index].mutex);
|
432
419
|
}
|
433
420
|
|
@@ -441,7 +428,7 @@ struct winfd fd_to_winfd(int fd)
|
|
441
428
|
|
442
429
|
CHECK_INIT_POLLING;
|
443
430
|
|
444
|
-
if (fd
|
431
|
+
if (fd < 0)
|
445
432
|
return INVALID_WINFD;
|
446
433
|
|
447
434
|
for (i=0; i<MAX_FDS; i++) {
|
@@ -651,15 +638,7 @@ int usbi_close(int fd)
|
|
651
638
|
if (_index < 0) {
|
652
639
|
errno = EBADF;
|
653
640
|
} else {
|
654
|
-
|
655
|
-
// Must be a different event for each end of the pipe
|
656
|
-
CloseHandle(poll_fd[_index].overlapped->hEvent);
|
657
|
-
free(poll_fd[_index].overlapped);
|
658
|
-
}
|
659
|
-
r = _close(poll_fd[_index].fd);
|
660
|
-
if (r != 0) {
|
661
|
-
errno = EIO;
|
662
|
-
}
|
641
|
+
free_overlapped(poll_fd[_index].overlapped);
|
663
642
|
poll_fd[_index] = INVALID_WINFD;
|
664
643
|
LeaveCriticalSection(&_poll_fd[_index].mutex);
|
665
644
|
}
|