Skip to content

Commit

Permalink
mraa: Add patch to fix "uv__has_active_reqs" assertions
Browse files Browse the repository at this point in the history
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
jan-kiszka committed Dec 5, 2022
1 parent 1177b3c commit 35c4a58
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 0 deletions.
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

1 change: 1 addition & 0 deletions recipes-app/mraa/mraa_2.2.0+git.bb
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down

0 comments on commit 35c4a58

Please sign in to comment.