Skip to content

Commit 1593284

Browse files
authored
Merge pull request #15 from ianthomas23/sync_get_stdin
Use blocking synchronous get_stdin for input_request
1 parent d9279c0 commit 1593284

File tree

3 files changed

+29
-11
lines changed

3 files changed

+29
-11
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
strategy:
1717
fail-fast: false
1818
matrix:
19-
emsdk: ["3.1.45", "latest"]
19+
emsdk: ["3.1.73", "4.0.3"]
2020
steps:
2121
- uses: actions/checkout@v4
2222
- uses: docker-practice/actions-setup-docker@master

BuildWasmDockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
ARG EMSCRIPTEN_VER=3.1.45
1+
ARG EMSCRIPTEN_VER=3.1.73
22
FROM emscripten/emsdk:$EMSCRIPTEN_VER
33

44
ARG USER_ID

src/xserver_emscripten.cpp

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,22 @@ namespace ems = emscripten;
1313

1414
namespace xeus
1515
{
16-
EM_JS(ems::EM_VAL, get_stdin, (), {
17-
return Asyncify.handleAsync(() => {
18-
return globalThis.get_stdin().then(msg => {
19-
return Emval.toHandle(msg);
20-
});
21-
});
22-
});
16+
// Get input from stdin by sending the input_request message and receiving back the
17+
// input_reply. This is blocking (synchronous) from the point of view of the lite
18+
// kernel running in its WebWorker. The implementation in the main UI thread is async.
19+
//
20+
// It calls the globalThis.get_stdin defined in jupyterlite/xeus.
21+
//
22+
// Here implemented as a C function which is simpler than the equivalent EM_JS
23+
// function:
24+
// EM_JS(ems::EM_VAL, get_stdin, (ems::EM_VAL input_request), {
25+
// return Emval.toHandle(globalThis.get_stdin(Emval.toValue(input_request)));
26+
// });
27+
// and the EM_JS function fails at runtime as it lacks an autogenerated signature.
28+
inline ems::val get_stdin(ems::val input_request)
29+
{
30+
return emscripten::val::global("self").call<ems::val>("get_stdin", input_request);
31+
}
2332

2433
// we use this instead of EM_JS since this is more robust.
2534
// EM_JS functions where somewhat undefined / buggy when
@@ -94,11 +103,20 @@ namespace xeus
94103

95104
void xserver_emscripten::send_stdin_impl(xmessage message)
96105
{
97-
post_kernel_message("stdin", js_message_from_xmessage(message, true));
98106
// Block until a response to the input request is received.
99-
ems::val js_message = ems::val::take_ownership(get_stdin());
107+
// input_request messages are sent via get_stdin rather than post_kernel_message.
108+
ems::val msg = js_message_from_xmessage(message, true);
109+
msg.set("channel", emscripten::val("stdin"));
110+
ems::val js_message = get_stdin(msg);
111+
100112
try
101113
{
114+
if (js_message.hasOwnProperty("error"))
115+
{
116+
std::string error_msg = js_message["error"].as<std::string>();
117+
throw std::runtime_error(error_msg);
118+
}
119+
102120
auto reply = xmessage_from_js_message(js_message);
103121
xserver::notify_stdin_listener(std::move(reply));
104122
}

0 commit comments

Comments
 (0)