Skip to content

Fix ENVIRONMENT_IS_WORKER detection on Deno #22778

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 29, 2024

Conversation

kleisauke
Copy link
Collaborator

importScripts() is always undefined on Deno.

`importScripts()` is always `undefined` on Deno.
@kleisauke
Copy link
Collaborator Author

Test case:

Before:

$ cat > test.c << EOF
#include <assert.h>
#include <pthread.h>
#include <stdio.h>

#include <emscripten/em_asm.h>

void* worker_thread(void *arg) {
  int is_worker = EM_ASM_INT(return ENVIRONMENT_IS_WORKER);
  printf("ENVIRONMENT_IS_WORKER: %d\n", is_worker);
  return NULL;
}

int main() {
  int is_worker = EM_ASM_INT(return ENVIRONMENT_IS_WORKER);
  printf("ENVIRONMENT_IS_WORKER: %d\n", is_worker);

  pthread_t thread;
  pthread_create(&thread, NULL, worker_thread, NULL);
  pthread_join(thread, NULL);

  return 0;
}
EOF
$ emcc test.c -o test.js -sASSERTIONS=0 -pthread -sEXIT_RUNTIME
$ node test.js
ENVIRONMENT_IS_WORKER: 0
ENVIRONMENT_IS_WORKER: 1
$ emcc test.c -o test.mjs -sENVIRONMENT=web,worker -sASSERTIONS=0 -pthread
$ echo "import Module from './test.mjs';await Module();Deno.exit()" | deno run --allow-read -
ENVIRONMENT_IS_WORKER: 0 [repeated x times until OOM]

After:

$ emcc test.c -o test.mjs -sENVIRONMENT=web,worker -sASSERTIONS=0 -pthread
$ echo "import Module from './test.mjs';await Module();Deno.exit()" | deno run --allow-read -
ENVIRONMENT_IS_WORKER: 0
ENVIRONMENT_IS_WORKER: 1

@kripken
Copy link
Member

kripken commented Oct 23, 2024

Looks reasonable to me. The downside is maybe a few more bytes in size, but I don't see a way around that, and it mostly affects pthreads builds (which are larger anyhow).

other.test_no_pthread on CI will need to be updated a little, it looks like (it greps for Worker, which this PR adds; can first replace WorkerGlobalScope with another string, if there isn't anything nicer).

// Dummy importScripts. The presence of this global is used
// to detect that we are running on a Worker.
// TODO(sbc): Find another way?
importScripts: () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little confused because you say that deno never defines importScripts, but from the looks of this code it seems that node doesn't define it either. Isn't the point of this line to inject it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, you're right. Node.js doesn't define importScripts either.

const { Worker, isMainThread } = require('node:worker_threads');

if (isMainThread) {
  // This re-loads the current file inside a Worker instance.
  new Worker(__filename);
} else {
  console.log(typeof importScripts);  // Prints 'undefined'.
}

Commit 4bab494 removes this altogether, since ENVIRONMENT_IS_WORKER no longer depends on this dummy symbol on Node.js:

ENVIRONMENT_IS_WORKER = !worker_threads.isMainThread;

(I can separate this change into its own PR if needed)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that ENVIRONMENT_IS_NODE is false on Deno. IIUC, Deno tends to favor standard Web Platform APIs over proprietary ones and wasn't originally designed to be a drop-in replacement for Node.js.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deno does have a Node.js compatibility layer these days (they started to compromise on that at some point, though they did start with "pure Web APIs" IIRC). I wonder if maybe we can make IS_NODE also accept deno, for simplicity? Separate from this PR of course. (And if it isn't trivial, then #12203 is probably the best long-term plan instead.)

This PR itself lgtm as is. Unless @sbc100 you had more thoughts?

@sbc100 sbc100 merged commit 31f9fb3 into emscripten-core:main Oct 29, 2024
28 checks passed
@kleisauke kleisauke deleted the deno-worker-compat branch October 30, 2024 09:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants