-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mraa: Add patch to fix "uv__has_active_reqs" assertions
See the included patch for more details. Related mraa PR is eclipse/mraa#1102. Fixes #386 Signed-off-by: Jan Kiszka <[email protected]>
- Loading branch information
1 parent
1177b3c
commit 35c4a58
Showing
2 changed files
with
139 additions
and
0 deletions.
There are no files selected for viewing
138 changes: 138 additions & 0 deletions
138
recipes-app/mraa/files/0001-gpio-Fix-JS-binding-regarding-interrupt-injections.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
From b10341fae399f8c25887c348af9577640b1e233e Mon Sep 17 00:00:00 2001 | ||
From: Jan Kiszka <[email protected]> | ||
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 <[email protected]> | ||
--- | ||
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 <stdexcept> | ||
|
||
#if defined(SWIGJAVASCRIPT) | ||
-#if NODE_MODULE_VERSION >= 0x000D | ||
#include <uv.h> | ||
#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<v8::Value> 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<v8::Function>::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<v8::Function> m_v8isr; | ||
#endif | ||
}; | ||
-- | ||
2.35.3 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ inherit dpkg | |
DESCRIPTION = "Low Level Skeleton Library for Communication on GNU/Linux platforms" | ||
MAINTAINER = "[email protected]" | ||
SRC_URI += "git://github.com/eclipse/mraa.git;protocol=https \ | ||
file://0001-gpio-Fix-JS-binding-regarding-interrupt-injections.patch \ | ||
file://rules" | ||
SRCREV = "8b1c54934e80edc2d36abac9d9c96fe1e01cb669" | ||
|
||
|