diff options
Diffstat (limited to '0001-function-Always-initialize-callback-return-value.patch')
-rw-r--r-- | 0001-function-Always-initialize-callback-return-value.patch | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/0001-function-Always-initialize-callback-return-value.patch b/0001-function-Always-initialize-callback-return-value.patch new file mode 100644 index 0000000..4ab69a8 --- /dev/null +++ b/0001-function-Always-initialize-callback-return-value.patch @@ -0,0 +1,67 @@ +From 4cbaa23f1f4a3510176a1f38489834203f71b2b6 Mon Sep 17 00:00:00 2001 +From: Sebastian Keller <skeller@gnome.org> +Date: Thu, 16 Mar 2023 22:35:49 +0100 +Subject: [PATCH] function: Always initialize callback return value + +When callback_closure() exits early, for example due to being called +during GC, the return value would not be initialized. This value is +often non-zero. If the callback is a source func of an idle or a timeout +this would then get interpreted as G_SOURCE_CONTINUE and the same would +repeat in the next iteration. If this happens fast enough, this results +in the entire process being seemingly frozen while spamming the log with +error messages. + +To fix this always initialize the return value to 0 or a comparable +neutral value. + +Related: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/1868 +--- + gi/function.cpp | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/gi/function.cpp b/gi/function.cpp +index 7c0064c8..5d69ed8a 100644 +--- a/gi/function.cpp ++++ b/gi/function.cpp +@@ -308,6 +308,15 @@ void GjsCallbackTrampoline::callback_closure(GIArgument** args, void* result) { + JSContext *context; + GITypeInfo ret_type; + ++ g_callable_info_load_return_type(m_info, &ret_type); ++ ++ // Fill in the result with some hopefully neutral value ++ if (g_type_info_get_tag(&ret_type) != GI_TYPE_TAG_VOID) { ++ GIArgument argument = {}; ++ gjs_gi_argument_init_default(&ret_type, &argument); ++ set_return_ffi_arg_from_giargument(&ret_type, result, &argument); ++ } ++ + if (G_UNLIKELY(!gjs_closure_is_valid(m_js_function))) { + warn_about_illegal_js_callback( + "during shutdown", +@@ -382,7 +391,6 @@ void GjsCallbackTrampoline::callback_closure(GIArgument** args, void* result) { + + JS::RootedValue rval(context); + +- g_callable_info_load_return_type(m_info, &ret_type); + GIArgument* error_argument = nullptr; + + if (g_callable_info_can_throw_gerror(m_info)) +@@ -406,14 +414,6 @@ void GjsCallbackTrampoline::callback_closure(GIArgument** args, void* result) { + m_info.ns(), m_info.name()); + } + +- // Fill in the result with some hopefully neutral value +- if (g_type_info_get_tag(&ret_type) != GI_TYPE_TAG_VOID) { +- GIArgument argument = {}; +- g_callable_info_load_return_type(m_info, &ret_type); +- gjs_gi_argument_init_default(&ret_type, &argument); +- set_return_ffi_arg_from_giargument(&ret_type, result, &argument); +- } +- + // If the callback has a GError** argument and invoking the closure + // returned an error, try to make a GError from it + if (error_argument && rval.isObject()) { +-- +2.35.1 + |