Skip to content

Commit 2c15c6e

Browse files
authored
[embind] Fix cross-thread check for deleted vals (#20395)
1 parent 1e7838b commit 2c15c6e

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

system/include/emscripten/val.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,8 @@ class val {
399399
}
400400

401401
~val() {
402-
if (EM_VAL handle = as_handle()) {
403-
internal::_emval_decref(handle);
402+
if (handle) {
403+
internal::_emval_decref(as_handle());
404404
handle = 0;
405405
}
406406
}

test/test_core.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7779,7 +7779,6 @@ def test_embind_val_assignment(self):
77797779
@node_pthreads
77807780
def test_embind_val_cross_thread(self):
77817781
self.emcc_args += ['--bind']
7782-
self.setup_node_pthreads()
77837782
create_file('test_embind_val_cross_thread.cpp', r'''
77847783
#include <emscripten.h>
77857784
#include <emscripten/val.h>
@@ -7804,6 +7803,34 @@ def test_embind_val_cross_thread(self):
78047803
''')
78057804
self.do_runf('test_embind_val_cross_thread.cpp', 'val accessed from wrong thread', assert_returncode=NON_ZERO)
78067805

7806+
@node_pthreads
7807+
def test_embind_val_cross_thread_deleted(self):
7808+
self.emcc_args += ['--bind']
7809+
create_file('test_embind_val_cross_thread.cpp', r'''
7810+
#include <emscripten.h>
7811+
#include <emscripten/val.h>
7812+
#include <thread>
7813+
#include <stdio.h>
7814+
#include <optional>
7815+
7816+
using emscripten::val;
7817+
7818+
int main(int argc, char **argv) {
7819+
// Create a storage for value handles on the main thread.
7820+
std::optional<val> opt_value;
7821+
std::thread([&] {
7822+
// Set to a value handle from a different thread.
7823+
val& value = opt_value.emplace(1);
7824+
// Move out from the optional storage so that we free the value on the same thread.
7825+
val moved_out = std::move(value);
7826+
}).join();
7827+
// Now std::optional is initialized but with a deleted value handle.
7828+
// There should be no cross-thread error here when it tries to free that value,
7829+
// because the value has already been deleted on the correct thread.
7830+
}
7831+
''')
7832+
self.do_runf('test_embind_val_cross_thread.cpp')
7833+
78077834
def test_embind_dynamic_initialization(self):
78087835
self.emcc_args += ['-lembind']
78097836
self.do_run_in_out_file_test('embind/test_dynamic_initialization.cpp')

0 commit comments

Comments
 (0)