Comments (6)
Can you add a console.log
to the end of write_data
function and just before the call the emscripten_sleep
to confirm that write_data
doesn't return to the caller until after the last of the 3 await
statements?
I imagine what is happening here is that the webserial API requires you to return to event loop in order to do what i needs to do. emscripten_sleep
is just one way to return to the event loop. You could also try using emscripten_set_main_loop
.
BTW is this code running in on the main browser thread? If so I guess you have to be returning to the event loops anyway.
As always, could you share the full set of link flags you are using?
from emscripten.
Thank you for your reply!
First I'll give some more context, I am porting avrdude to webassembly, and yes it runs on the main browser thread, but I get the same results using pthread.
Here are my flags for with pthread:
-- CMAKE_CXX_FLAGS: -fPIC -s ALLOW_BLOCKING_ON_MAIN_THREAD -s PROXY_TO_PTHREAD -s EXPORT_NAME=avrdude -pthread -s ASYNCIFY_IMPORTS=['serialPortWrite','serialPortRecv'] -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s MAIN_MODULE -s WASM=1 -s FORCE_FILESYSTEM -s ASYNCIFY=1 -s INVOKE_RUN=0 -s WASM_BIGINT=1 -s MODULARIZE=1 -s EXPORT_KEEPALIVE=1 --bind -s "EXPORTED_FUNCTIONS=['_startAvrdude','_main','_malloc']" -s EXPORTED_RUNTIME_METHODS='["cwrap", "writeStringToMemory", "FS", "allocate", "intArrayFromString"]'
And without:
-- CMAKE_CXX_FLAGS: -fPIC -s ASYNCIFY_IMPORTS=['serialPortWrite','serialPortRecv'] -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s MAIN_MODULE -s WASM=1 -s FORCE_FILESYSTEM -s ASYNCIFY=1 -s INVOKE_RUN=0 -s WASM_BIGINT=1 -s MODULARIZE=1 -s EXPORT_KEEPALIVE=1 --bind -s "EXPORTED_FUNCTIONS=['_startAvrdude','_main','_malloc']" -s EXPORTED_RUNTIME_METHODS='["cwrap", "writeStringToMemory", "FS", "allocate", "intArrayFromString"]'
My first thought was also that the write_data function was completed later or something but it is not sadly. But here is the updated code and respective output just to make sure.
EM_ASYNC_JS(void, write_data, (EM_VAL data), {
data = new Uint8Array(Emval.toValue(data));
console.log("Sending: ", data);
const port = window.activePort;
await window.writeStream.ready;
await window.writeStream.write(data);
await window.writeStream.ready;
console.log("Data sent");
});
void serialPortWrite(const unsigned char *buf, size_t len) {
std::vector<unsigned char> data(buf, buf + len);
write_data(val(typed_memory_view(data.size(), data.data())).as_handle());
printf("Data sent from C\n");
emscripten_sleep(0);
}
Output:
Sending: Uint8Array(2) [48, 32, buffer: ArrayBuffer(2), byteLength: 2, byteOffset: 0, length: 2, Symbol(Symbol.toStringTag): 'Uint8Array'] avrdude.js:8 Data sent avrdude.js:8 Data sent from C
from emscripten.
What is your program doing right after the serialPortWrite
? Assuming its sitting the event loop then I don't see who emscripten_sleep
can be helping since all it does is return to the event loop anyway.
from emscripten.
It runs some more webassembly code it sends the 48,32 packet three times to my arduino. When it is done with those operations it will read the return data of the arduino.
EM_ASYNC_JS(void, read_data, (int timeoutMs), {
const reader = window.activePort.readable.getReader();
console.log("Reading data");
async function receive() {
const { value } = await reader.read();
return value;
}
async function timeout(timeoutMs) {
await new Promise(resolve => setTimeout(resolve, timeoutMs));
return "timeout";
}
var returnBuffer = new Uint8Array();
while (true) {
let result = await Promise.race([receive(), timeout(timeoutMs)]);
if (result instanceof Uint8Array) {
// check if it is twice the same data so check if the first half is the same as the second half if so remove the second half
let firstHalf = result.slice(0, result.length / 2);
let secondHalf = result.slice(result.length / 2, result.length);
if (firstHalf.every((value, index) => value === secondHalf[index])) {
result = firstHalf;
}
console.log("Received: ", result);
const ptr = window.funcs._malloc(result.length * Uint8Array.BYTES_PER_ELEMENT);
window.funcs.HEAPU8.set(result, ptr);
// Call the C++ function with the pointer and the length of the array
window.funcs._dataCallback(ptr, result.length);
break;
} else {
console.log("Timeout", result);
break;
}
}
reader.releaseLock();
return;
});
int serialPortRecv(unsigned char *buf, size_t len, int timeoutMs) {
std::vector<unsigned char> data = {};
data.reserve(len);
// check if there is leftover data from previous reads
if (!readBuffer.empty()) {
if (readBuffer.size() >= len) {
data = std::vector<unsigned char>(readBuffer.begin(), readBuffer.begin() + len);
readBuffer.erase(readBuffer.begin(), readBuffer.begin() + len);
std::copy(data.begin(), data.end(), buf);
return 0;
} else {
data = std::vector<unsigned char>(readBuffer.begin(), readBuffer.end());
readBuffer.clear();
}
}
read_data(timeoutMs);
if (!readBuffer.empty()) {
// check how much data is needed and add that much to the buffer
if (readBuffer.size() >= len) {
data = std::vector<unsigned char>(readBuffer.begin(), readBuffer.begin() + len);
readBuffer.erase(readBuffer.begin(), readBuffer.begin() + len);
} else {
data = std::vector<unsigned char>(readBuffer.begin(), readBuffer.end());
readBuffer.clear();
}
}
if (data.empty()) {
// fill data buf with 1s if no data was received
printf("No data received\n");
return -1;
} else {
std::copy(data.begin(), data.end(), buf);
}
return 0;
}
from emscripten.
Some more testing reveals that the requirement is 300ms which works fine, but makes this code incredibly slow.
from emscripten.
from emscripten.
Related Issues (20)
- ASYNCIFY and INCOMING_MODULE_JS_API HOT 3
- thread wasm64 HOT 2
- Multithreading worker issue HOT 3
- Improve support for keyboard input on mobile browsers HOT 4
- emcc/wasm-ld fails autoconf sanity check HOT 3
- Error after setting GL_UNPACK_ROW_LENGTH HOT 10
- emconfigure sets both, CROSS_COMPILE and CC to absolute path, which seems to fail with man projects HOT 2
- Dynamic linking broken in 3.1.57
- `alignof(long double) == 8` even though `sizeof(long double) == 16`—why? HOT 2
- `FS.stat` has inconsistent `[a/m/c]time` values in WasmFS HOT 4
- pthread workers fail to run when ENVIRONMENT=worker only HOT 9
- Component model support in Emscripten HOT 1
- --emit-tsd does not output function argument names HOT 2
- Can't preload files/shared libs in service worker due to lack of XHR [PR OPEN]
- isinf() can return -1 HOT 4
- missing FE_xx defines HOT 7
- Building failure after switching from 3.1.47 to 3.1.57 HOT 15
- Passing array of arrays to emscripten HOT 1
- --extern-pre-js no longer accessible in Workers HOT 1
- Operator Overloading Error in system/lib/libcxx/include/__algorithm/sort.h HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from emscripten.