-
Notifications
You must be signed in to change notification settings - Fork 0
/
libusb.patch
68 lines (65 loc) · 2.35 KB
/
libusb.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
diff --git a/libusb/os/emscripten_webusb.cpp b/libusb/os/emscripten_webusb.cpp
index f19c1bd3..bbaffec7 100644
--- a/libusb/os/emscripten_webusb.cpp
+++ b/libusb/os/emscripten_webusb.cpp
@@ -58,8 +58,13 @@ EM_JS(EM_VAL, usbi_em_promise_catch, (EM_VAL handle), {
promise = promise.then(
value => ({error : 0, value}),
error => {
- console.error(error);
let errorCode = -99; // LIBUSB_ERROR_OTHER
+ if (error == Symbol.for('libusb.cancelled')) {
+ // LIBUSB_ERROR_INTERRUPTED
+ errorCode = -10;
+ } else {
+ console.error(error);
+ }
if (error instanceof DOMException) {
const ERROR_CODES = {
// LIBUSB_ERROR_IO
@@ -134,6 +139,30 @@ EM_JS(EM_VAL, usbi_em_device_safe_open_close, (EM_VAL device, bool open), {
});
return Emval.toHandle(promiseChain);
});
+
+EM_JS(void, usbi_em_cancel_transfer_promise, (usbi_transfer *transfer), {
+ if (Module.libusbTransferPromises[transfer]) {
+ Module.libusbTransferPromises[transfer].cancel();
+ delete Module.libusbTransferPromises[transfer];
+ }
+});
+
+EM_JS(EM_VAL, usbi_em_wrap_transfer_promise, (usbi_transfer *transfer, EM_VAL handle), {
+ let cancel;
+ const promise = Emval.toValue(handle);
+ const promiseWrapped = Promise.race([
+ promise,
+ new Promise((resolve, reject) => cancel = reject)
+ ]).finally(() => {
+ delete Module.libusbTransferPromises[transfer];
+ });
+ promiseWrapped.cancel = () => cancel(Symbol.for('libusb.cancelled'));
+ // save promise
+ Module.libusbTransferPromises = Module.libusbTransferPromises || {};
+ Module.libusbTransferPromises[transfer] = promiseWrapped;
+ // return
+ return Emval.toHandle(promiseWrapped);
+});
// clang-format on
libusb_transfer_status getTransferStatus(const val& transfer_result) {
@@ -769,6 +798,7 @@ int em_submit_transfer(usbi_transfer* itransfer) {
default:
return LIBUSB_ERROR_NOT_SUPPORTED;
}
+ transfer_promise = val::take_ownership(usbi_em_wrap_transfer_promise(itransfer, transfer_promise.as_handle()));
// Not a coroutine because we don't want to block on this promise, just
// schedule an asynchronous callback.
promiseThen(CaughtPromise(std::move(transfer_promise)),
@@ -785,6 +815,9 @@ void em_clear_transfer_priv(usbi_transfer* itransfer) {
}
int em_cancel_transfer(usbi_transfer* itransfer) {
+ runOnMain([itransfer]() {
+ usbi_em_cancel_transfer_promise(itransfer);
+ });
return LIBUSB_SUCCESS;
}