diff --git a/src/bindings/connection.cpp b/src/bindings/connection.cpp index d6e2ffa41..eecab4cc3 100644 --- a/src/bindings/connection.cpp +++ b/src/bindings/connection.cpp @@ -1,8 +1,6 @@ #include "connection.h" #include "error.h" -#include - namespace vips { Source Source::new_from_file(const std::string &filename) { @@ -35,10 +33,11 @@ int64_t SourceCustom::read_handler(VipsSourceCustom *source, void *buffer, if (self->read_callback == nullptr) return -1; - // Ensure that we call the JS function on the main thread, see: - // https://github.com/emscripten-core/emscripten/issues/11317 - int64_t bytes_read = emscripten_sync_run_in_main_runtime_thread( - EM_FUNC_SIG_JPJ, self->read_callback, buffer, length); + int64_t bytes_read; + proxy_sync([&]() { + bytes_read = self->read_callback(buffer, length); + }); + return bytes_read; } @@ -48,8 +47,11 @@ int64_t SourceCustom::seek_handler(VipsSourceCustom *source, int64_t offset, if (self->seek_callback == nullptr) return -1; - int64_t new_pos = emscripten_sync_run_in_main_runtime_thread( - EM_FUNC_SIG_JJI, self->seek_callback, offset, whence); + int64_t new_pos; + proxy_sync([&]() { + new_pos = self->seek_callback(offset, whence); + }); + return new_pos; } @@ -91,8 +93,11 @@ int64_t TargetCustom::write_handler(VipsTargetCustom *target, if (self->write_callback == nullptr) return -1; - int64_t bytes_written = emscripten_sync_run_in_main_runtime_thread( - EM_FUNC_SIG_JPJ, self->write_callback, buffer, length); + int64_t bytes_written; + proxy_sync([&]() { + bytes_written = self->write_callback(buffer, length); + }); + return bytes_written; } @@ -105,8 +110,11 @@ int64_t TargetCustom::read_handler(VipsTargetCustom *target, void *buffer, if (self->read_callback == nullptr) return -1; - int64_t bytes_read = emscripten_sync_run_in_main_runtime_thread( - EM_FUNC_SIG_JPJ, self->read_callback, buffer, length); + int64_t bytes_read; + proxy_sync([&]() { + bytes_read = self->read_callback(buffer, length); + }); + return bytes_read; } @@ -116,8 +124,11 @@ int64_t TargetCustom::seek_handler(VipsTargetCustom *target, int64_t offset, if (self->seek_callback == nullptr) return -1; - int64_t new_pos = emscripten_sync_run_in_main_runtime_thread( - EM_FUNC_SIG_JJI, self->seek_callback, offset, whence); + int64_t new_pos; + proxy_sync([&]() { + new_pos = self->seek_callback(offset, whence); + }); + return new_pos; } @@ -126,9 +137,14 @@ int TargetCustom::end_handler(VipsTargetCustom *target, void *user) { if (self->end_callback == nullptr) return 0; - return emscripten_sync_run_in_main_runtime_thread(EM_FUNC_SIG_I, - self->end_callback); + int result; + proxy_sync([&]() { + result = self->end_callback(); + }); + + return result; } + void TargetCustom::set_write_callback(emscripten::val js_func) { emscripten::val ptr = emscripten::val::module_property("addFunction")( js_func, emscripten::val("jpj")); diff --git a/src/bindings/image.cpp b/src/bindings/image.cpp index 15e038441..1e94bede4 100644 --- a/src/bindings/image.cpp +++ b/src/bindings/image.cpp @@ -98,10 +98,9 @@ void Image::eval_handler(VipsImage *image, VipsProgress *progress, void *user) { if (self->progress_callback == nullptr) return; - // Ensure that we call the JS function on the main thread, see: - // https://github.com/emscripten-core/emscripten/issues/11317 - emscripten_sync_run_in_main_runtime_thread( - EM_FUNC_SIG_VI, self->progress_callback, progress->percent); + proxy_sync([&]() { + self->progress_callback(progress->percent); + }); } void Image::set_progress_callback(emscripten::val js_func) { diff --git a/src/bindings/image.h b/src/bindings/image.h index d8b2b3be4..e95037509 100644 --- a/src/bindings/image.h +++ b/src/bindings/image.h @@ -11,7 +11,6 @@ #include #include -#include namespace vips { diff --git a/src/bindings/utils.cpp b/src/bindings/utils.cpp index 3a8d72928..dbe663a9c 100644 --- a/src/bindings/utils.cpp +++ b/src/bindings/utils.cpp @@ -2,6 +2,9 @@ #include "option.h" +#include +#include + namespace vips { std::vector blend_modes_to_int(emscripten::val v) { @@ -39,4 +42,15 @@ std::vector invert(const std::vector &vector) { return new_vector; } +static void run(void *arg) { + std::function *f = reinterpret_cast *>(arg); + (*f)(); +} + +bool proxy_sync(const std::function &func) { + em_proxying_queue *q = emscripten_proxy_get_system_queue(); + return emscripten_proxy_sync(q, emscripten_main_runtime_thread_id(), run, + (void *)&func); +} + } // namespace vips diff --git a/src/bindings/utils.h b/src/bindings/utils.h index 0d6d11062..ce7b0fc46 100644 --- a/src/bindings/utils.h +++ b/src/bindings/utils.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -71,4 +72,10 @@ std::vector negate(const std::vector &vector); std::vector invert(const std::vector &vector); +/** + * Ensure that we call JS functions on the main runtime thread, see: + * https://github.com/emscripten-core/emscripten/issues/11317 + */ +bool proxy_sync(const std::function &func); + } // namespace vips