diff --git a/recipes-app/mraa/files/0001-gpio-Fix-JS-binding-regarding-interrupt-injections.patch b/recipes-app/mraa/files/0001-gpio-Fix-JS-binding-regarding-interrupt-injections.patch new file mode 100644 index 000000000..773c3547c --- /dev/null +++ b/recipes-app/mraa/files/0001-gpio-Fix-JS-binding-regarding-interrupt-injections.patch @@ -0,0 +1,138 @@ +From b10341fae399f8c25887c348af9577640b1e233e Mon Sep 17 00:00:00 2001 +From: Jan Kiszka +Date: Mon, 5 Dec 2022 11:45:15 +0100 +Subject: [PATCH] gpio: Fix JS binding regarding interrupt injections + +According to [1] and based on stress tests, it is not correct to call +uv_queue_work outside of the loop thread. We rather need to use the +async API of libuv. That even simplifies things. + +Resolves "uv__queue_done: Assertion `uv__has_active_reqs(req->loop)' failed" +errors that were easy to trigger by multiple DIs being used in parallel. +See also [2]. + +[1] https://github.com/libuv/libuv/discussions/3847 +[2] https://github.com/siemens/meta-iot2050/issues/386 + +Signed-off-by: Jan Kiszka +--- + api/mraa/gpio.hpp | 37 +++++++++++++++++++++---------------- + 1 file changed, 21 insertions(+), 16 deletions(-) + +diff --git a/api/mraa/gpio.hpp b/api/mraa/gpio.hpp +index 8fc0881..c41d527 100644 +--- a/api/mraa/gpio.hpp ++++ b/api/mraa/gpio.hpp +@@ -31,10 +31,10 @@ + #include + + #if defined(SWIGJAVASCRIPT) +-#if NODE_MODULE_VERSION >= 0x000D + #include + #endif +-#endif ++ ++#define container_of(ptr, type, member) ((type*) ((char*) (ptr) - offsetof(type, member))) + + namespace mraa + { +@@ -124,6 +124,10 @@ class Gpio + if (!owner) { + mraa_gpio_owner(m_gpio, 0); + } ++ ++#if defined(SWIGJAVASCRIPT) ++ uv_async_init(uv_default_loop(), &m_async, v8isr); ++#endif + } + /** + * Gpio Constructor, takes a pointer to the GPIO context and initialises +@@ -137,6 +141,9 @@ class Gpio + if (m_gpio == NULL) { + throw std::invalid_argument("Invalid GPIO context"); + } ++#if defined(SWIGJAVASCRIPT) ++ uv_async_init(uv_default_loop(), &m_async, v8isr); ++#endif + } + /** + * Gpio object destructor, this will only unexport the gpio if we where +@@ -146,6 +153,9 @@ class Gpio + { + if (m_gpio != NULL) { + mraa_gpio_close(m_gpio); ++#if defined(SWIGJAVASCRIPT) ++ uv_close((uv_handle_t*) &m_async, NULL); ++#endif + } + } + /** +@@ -156,6 +166,9 @@ class Gpio + { + mraa_gpio_close(m_gpio); + m_gpio = NULL; ++#if defined(SWIGJAVASCRIPT) ++ uv_close((uv_handle_t*) &m_async, NULL); ++#endif + } + /** + * Set the edge mode for ISR +@@ -176,12 +189,12 @@ class Gpio + } + #elif defined(SWIGJAVASCRIPT) + static void +- v8isr(uv_work_t* req, int status) ++ v8isr(uv_async_t* async) + { + #if NODE_MODULE_VERSION >= 0x000D + v8::HandleScope scope(v8::Isolate::GetCurrent()); + #endif +- mraa::Gpio* This = (mraa::Gpio*) req->data; ++ mraa::Gpio* This = container_of(async, mraa::Gpio, m_async); + int argc = 1; + v8::Local argv[] = { SWIGV8_INTEGER_NEW(-1) }; + #if NODE_MODULE_VERSION >= 0x000D +@@ -194,21 +207,12 @@ class Gpio + #else + This->m_v8isr->Call(SWIGV8_CURRENT_CONTEXT()->Global(), argc, argv); + #endif +- delete req; +- } +- +- static void +- nop(uv_work_t* req) +- { +- // Do nothing. + } + + static void +- uvwork(void* ctx) ++ trigger_async(void* async) + { +- uv_work_t* req = new uv_work_t; +- req->data = ctx; +- uv_queue_work(uv_default_loop(), req, nop, v8isr); ++ uv_async_send((uv_async_t*) async); + } + + Result +@@ -219,7 +223,7 @@ class Gpio + #else + m_v8isr = v8::Persistent::New(func); + #endif +- return (Result) mraa_gpio_isr(m_gpio, (mraa_gpio_edge_t) mode, &uvwork, this); ++ return (Result) mraa_gpio_isr(m_gpio, (mraa_gpio_edge_t) mode, trigger_async, &m_async); + } + #elif defined(SWIGJAVA) || defined(JAVACALLBACK) + Result +@@ -376,6 +380,7 @@ class Gpio + private: + mraa_gpio_context m_gpio; + #if defined(SWIGJAVASCRIPT) ++ uv_async_t m_async; + v8::Persistent m_v8isr; + #endif + }; +-- +2.35.3 + diff --git a/recipes-app/mraa/mraa_2.2.0+git.bb b/recipes-app/mraa/mraa_2.2.0+git.bb index 00e305cb0..4907290ff 100644 --- a/recipes-app/mraa/mraa_2.2.0+git.bb +++ b/recipes-app/mraa/mraa_2.2.0+git.bb @@ -12,6 +12,7 @@ inherit dpkg DESCRIPTION = "Low Level Skeleton Library for Communication on GNU/Linux platforms" MAINTAINER = "le.jin@siemens.com" SRC_URI += "git://github.com/eclipse/mraa.git;protocol=https \ + file://0001-gpio-Fix-JS-binding-regarding-interrupt-injections.patch \ file://rules" SRCREV = "8b1c54934e80edc2d36abac9d9c96fe1e01cb669"