Skip to content

Commit

Permalink
Use bare-structured-clone for passing thread data
Browse files Browse the repository at this point in the history
  • Loading branch information
kasperisager committed Mar 20, 2024
1 parent 8019cae commit d19bcf5
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 122 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ link_bare_module(bare bare-hrtime)
link_bare_module(bare bare-inspect)
link_bare_module(bare bare-module)
link_bare_module(bare bare-os)
link_bare_module(bare bare-structured-clone)
link_bare_module(bare bare-timers)
link_bare_module(bare bare-url)

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ Options include:
```js
{
// Optional data to pass to the thread
data: Buffer | ArrayBuffer | SharedArrayBuffer | External,
data: null,
// Optional file source, will be read from `filename` if neither `source` nor `callback` are provided
source: string | Buffer,
// Optional source encoding if `source` is a string
Expand Down
35 changes: 35 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"bare-os": "^2.0.0",
"bare-path": "^2.0.0",
"bare-repl": "^1.0.0",
"bare-structured-clone": "^1.0.1",
"bare-timers": "^2.0.0",
"bare-tty": "^3.0.0",
"bare-url": "^1.0.0",
Expand Down
22 changes: 15 additions & 7 deletions src/bare.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,28 @@ bare.addon = function addon (specifier) {
// statically resolvable to allow them to be included by the bundler.
switch (specifier) {
case '/node_modules/bare-buffer/':
pkg = require('bare-buffer/package.json')
pkg = require('bare-buffer/package')
break
case '/node_modules/bare-timers/':
pkg = require('bare-timers/package.json')
pkg = require('bare-timers/package')
break
case '/node_modules/bare-inspect/':
pkg = require('bare-inspect/package.json')
pkg = require('bare-inspect/package')
break
case '/node_modules/bare-hrtime/':
pkg = require('bare-hrtime/package.json')
pkg = require('bare-hrtime/package')
break
case '/node_modules/bare-os/':
pkg = require('bare-os/package.json')
pkg = require('bare-os/package')
break
case '/node_modules/bare-structured-clone/':
pkg = require('bare-structured-clone/package')
break
case '/node_modules/bare-url/':
pkg = require('bare-url/package.json')
pkg = require('bare-url/package')
break
case '/node_modules/bare-module/':
pkg = require('bare-module/package.json')
pkg = require('bare-module/package')
break
default:
throw new Error(`Unknown addon '${specifier}'`)
Expand Down Expand Up @@ -177,6 +180,10 @@ class Bare extends EventEmitter {
this.emit('resume')
}

_onthread (data) {
exports.Thread.self._ondata(data)
}

[Symbol.for('bare.inspect')] () {
return {
__proto__: { constructor: Bare },
Expand Down Expand Up @@ -243,6 +250,7 @@ bare.onteardown = exports._onteardown.bind(exports)
bare.onsuspend = exports._onsuspend.bind(exports)
bare.onidle = exports._onidle.bind(exports)
bare.onresume = exports._onresume.bind(exports)
bare.onthread = exports._onthread.bind(exports)

/**
* Step 8:
Expand Down
102 changes: 18 additions & 84 deletions src/runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,17 +151,11 @@ bare_runtime_on_before_exit (bare_runtime_t *runtime) {
err = js_get_named_property(env, exports, "onbeforeexit", &fn);
assert(err == 0);

bool is_set;
err = js_is_function(env, fn, &is_set);
js_value_t *global;
err = js_get_global(env, &global);
assert(err == 0);

if (is_set) {
js_value_t *global;
err = js_get_global(env, &global);
assert(err == 0);

js_call_function(env, global, fn, 0, NULL, NULL);
}
js_call_function(env, global, fn, 0, NULL, NULL);

err = js_close_handle_scope(env, scope);
assert(err == 0);
Expand Down Expand Up @@ -193,17 +187,11 @@ bare_runtime_on_exit (bare_runtime_t *runtime) {
err = js_get_named_property(env, exports, "onexit", &fn);
assert(err == 0);

bool is_set;
err = js_is_function(env, fn, &is_set);
js_value_t *global;
err = js_get_global(env, &global);
assert(err == 0);

if (is_set) {
js_value_t *global;
err = js_get_global(env, &global);
assert(err == 0);

js_call_function(env, global, fn, 0, NULL, NULL);
}
js_call_function(env, global, fn, 0, NULL, NULL);

err = js_close_handle_scope(env, scope);
assert(err == 0);
Expand Down Expand Up @@ -235,17 +223,11 @@ bare_runtime_on_teardown (bare_runtime_t *runtime, int *exit_code) {
err = js_get_named_property(env, exports, "onteardown", &fn);
assert(err == 0);

bool is_set;
err = js_is_function(env, fn, &is_set);
js_value_t *global;
err = js_get_global(env, &global);
assert(err == 0);

if (is_set) {
js_value_t *global;
err = js_get_global(env, &global);
assert(err == 0);

js_call_function(env, global, fn, 0, NULL, NULL);
}
js_call_function(env, global, fn, 0, NULL, NULL);

if (exit_code) {
js_value_t *val;
Expand Down Expand Up @@ -284,17 +266,11 @@ bare_runtime_on_suspend (bare_runtime_t *runtime) {
err = js_get_named_property(env, exports, "onsuspend", &fn);
assert(err == 0);

bool is_set;
err = js_is_function(env, fn, &is_set);
js_value_t *global;
err = js_get_global(env, &global);
assert(err == 0);

if (is_set) {
js_value_t *global;
err = js_get_global(env, &global);
assert(err == 0);

js_call_function(env, global, fn, 0, NULL, NULL);
}
js_call_function(env, global, fn, 0, NULL, NULL);

err = js_close_handle_scope(env, scope);
assert(err == 0);
Expand Down Expand Up @@ -335,17 +311,11 @@ bare_runtime_on_idle (bare_runtime_t *runtime) {
err = js_get_named_property(env, exports, "onidle", &fn);
assert(err == 0);

bool is_set;
err = js_is_function(env, fn, &is_set);
js_value_t *global;
err = js_get_global(env, &global);
assert(err == 0);

if (is_set) {
js_value_t *global;
err = js_get_global(env, &global);
assert(err == 0);

js_call_function(env, global, fn, 0, NULL, NULL);
}
js_call_function(env, global, fn, 0, NULL, NULL);

err = js_close_handle_scope(env, scope);
assert(err == 0);
Expand Down Expand Up @@ -375,17 +345,11 @@ bare_runtime_on_resume (bare_runtime_t *runtime) {
err = js_get_named_property(env, exports, "onresume", &fn);
assert(err == 0);

bool is_set;
err = js_is_function(env, fn, &is_set);
js_value_t *global;
err = js_get_global(env, &global);
assert(err == 0);

if (is_set) {
js_value_t *global;
err = js_get_global(env, &global);
assert(err == 0);

js_call_function(env, global, fn, 0, NULL, NULL);
}
js_call_function(env, global, fn, 0, NULL, NULL);

err = js_close_handle_scope(env, scope);
assert(err == 0);
Expand Down Expand Up @@ -781,36 +745,6 @@ bare_runtime_setup_thread (js_env_t *env, js_callback_info_t *info) {
assert(err == 0);

data.type = bare_thread_data_buffer;
} else {
err = js_is_arraybuffer(env, argv[2], &has_data);
assert(err == 0);

if (has_data) {
err = js_get_arraybuffer_info(env, argv[2], (void **) &data.buffer.base, (size_t *) &data.buffer.len);
assert(err == 0);

data.type = bare_thread_data_arraybuffer;
} else {
err = js_is_sharedarraybuffer(env, argv[2], &has_data);
assert(err == 0);

if (has_data) {
err = js_get_sharedarraybuffer_backing_store(env, argv[2], &data.backing_store);
assert(err == 0);

data.type = bare_thread_data_sharedarraybuffer;
} else {
err = js_is_external(env, argv[2], &has_data);
assert(err == 0);

if (has_data) {
err = js_get_value_external(env, argv[2], &data.external);
assert(err == 0);

data.type = bare_thread_data_external;
}
}
}
}

uint32_t stack_size;
Expand Down
31 changes: 8 additions & 23 deletions src/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,37 +83,22 @@ bare_thread_entry (void *data) {
assert(err == 0);
break;
}

case bare_thread_data_arraybuffer: {
void *data;
err = js_create_arraybuffer(runtime->env, thread->data.buffer.len, &data, &thread_data);
assert(err == 0);

memcpy(data, thread->data.buffer.base, thread->data.buffer.len);
break;
}

case bare_thread_data_sharedarraybuffer:
err = js_create_sharedarraybuffer_with_backing_store(runtime->env, thread->data.backing_store, NULL, NULL, &thread_data);
assert(err == 0);

err = js_release_arraybuffer_backing_store(runtime->env, thread->data.backing_store);
assert(err == 0);
break;

case bare_thread_data_external:
err = js_create_external(runtime->env, thread->data.external, NULL, NULL, &thread_data);
assert(err == 0);
break;
}

js_value_t *exports;
err = js_get_reference_value(env, runtime->exports, &exports);
assert(err == 0);

err = js_set_named_property(runtime->env, exports, "threadData", thread_data);
js_value_t *fn;
err = js_get_named_property(env, exports, "onthread", &fn);
assert(err == 0);

js_value_t *global;
err = js_get_global(env, &global);
assert(err == 0);

js_call_function(env, global, fn, 1, (js_value_t *[]){thread_data}, NULL);

err = js_close_handle_scope(env, scope);
assert(err == 0);

Expand Down
25 changes: 23 additions & 2 deletions src/thread.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* global bare, Bare */
const structuredClone = require('bare-structured-clone')

module.exports = exports = class Thread {
constructor (filename, opts, callback) {
Expand Down Expand Up @@ -32,6 +33,18 @@ module.exports = exports = class Thread {

if (typeof source === 'string') source = Buffer.from(source, encoding)

if (data !== null) {
const serialized = structuredClone.serialize(data)

const state = { start: 0, end: 0, buffer: null }
structuredClone.preencode(state, serialized)

state.buffer = Buffer.allocUnsafe(state.end)
structuredClone.encode(state, serialized)

data = state.buffer
}

this._handle = bare.setupThread(filename, source, data, stackSize)

Thread._threads.add(this)
Expand Down Expand Up @@ -78,8 +91,16 @@ module.exports = exports = class Thread {
}

class ThreadProxy {
get data () {
return ArrayBuffer.isView(bare.threadData) ? Buffer.coerce(bare.threadData) : bare.threadData
constructor () {
this.data = null
}

_ondata (data) {
if (data === null) return

const state = { start: 0, end: data.byteLength, buffer: data }

this.data = structuredClone.deserialize(structuredClone.decode(state))
}

[Symbol.for('bare.inspect')] () {
Expand Down
Loading

0 comments on commit d19bcf5

Please sign in to comment.