From 808d0ab67bb88012a948d0537ec47c1254390b69 Mon Sep 17 00:00:00 2001 From: han_hui_hui Date: Thu, 11 Jan 2024 03:10:19 +0000 Subject: [PATCH] fix pcre2 error , memory leak and log domains error --- ...sk-is-freed-on-a-graceful-disconnect.patch | 39 ++++ ...ort-add-version-macros-for-GLib-2.74.patch | 12 +- ...-fix-dropping-irrelevant-log-domains.patch | 128 ++++++++++++++ ...d-fall-back-to-interpretive-matching.patch | 120 +++++++++++++ ...ize-for-PCRE2-JIT-compiler-to-512KiB.patch | 166 ++++++++++++++++++ ...-minor-leak-in-g_build_user_data_dir.patch | 31 ++++ glib2.spec | 11 +- 7 files changed, 500 insertions(+), 7 deletions(-) create mode 100644 backport-Make-sure-the-GTask-is-freed-on-a-graceful-disconnect.patch create mode 100644 backport-gmessages-fix-dropping-irrelevant-log-domains.patch create mode 100644 backport-gregex-if-JIT-stack-limit-is-reached-fall-back-to-interpretive-matching.patch create mode 100644 backport-gregex-set-default-max-stack-size-for-PCRE2-JIT-compiler-to-512KiB.patch create mode 100644 backport-gutils-Fix-an-unlikely-minor-leak-in-g_build_user_data_dir.patch diff --git a/backport-Make-sure-the-GTask-is-freed-on-a-graceful-disconnect.patch b/backport-Make-sure-the-GTask-is-freed-on-a-graceful-disconnect.patch new file mode 100644 index 0000000..6ed1df6 --- /dev/null +++ b/backport-Make-sure-the-GTask-is-freed-on-a-graceful-disconnect.patch @@ -0,0 +1,39 @@ +From cabc49407371800733ada202fab721c9091b6fe6 Mon Sep 17 00:00:00 2001 +From: Pavel Sobolev +Date: Thu, 14 Sep 2023 15:42:24 +0300 +Subject: [PATCH] Make sure the `GTask` is freed on a graceful disconnect + +This fixes the memory leak in the case the connection has been +successfully closed by the peer. + + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/cabc49407371800733ada202fab721c9091b6fe6 + +--- + gio/gtcpconnection.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/gio/gtcpconnection.c b/gio/gtcpconnection.c +index 422b3dea52..e0865d859b 100644 +--- a/gio/gtcpconnection.c ++++ b/gio/gtcpconnection.c +@@ -206,6 +206,8 @@ async_close_finish (GTask *task, + g_task_return_error (task, error); + else + g_task_return_boolean (task, TRUE); ++ ++ g_object_unref (task); + } + + +@@ -231,7 +233,6 @@ close_read_ready (GSocket *socket, + else + { + async_close_finish (task, error); +- g_object_unref (task); + return FALSE; + } + } +-- +GitLab \ No newline at end of file diff --git a/backport-add-version-macros-for-GLib-2.74.patch b/backport-add-version-macros-for-GLib-2.74.patch index 1445a34..ca2bbd5 100644 --- a/backport-add-version-macros-for-GLib-2.74.patch +++ b/backport-add-version-macros-for-GLib-2.74.patch @@ -208,12 +208,12 @@ index e08c809019..143e048241 100644 +# define GLIB_DEPRECATED_TYPE_IN_2_74_FOR(f) +#endif + -+#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_74 -+# define GLIB_AVAILABLE_IN_2_74 GLIB_UNAVAILABLE(2, 74) -+# define GLIB_AVAILABLE_STATIC_INLINE_IN_2_74 GLIB_UNAVAILABLE_STATIC_INLINE(2, 74) -+# define GLIB_AVAILABLE_MACRO_IN_2_74 GLIB_UNAVAILABLE_MACRO(2, 74) -+# define GLIB_AVAILABLE_ENUMERATOR_IN_2_74 GLIB_UNAVAILABLE_ENUMERATOR(2, 74) -+# define GLIB_AVAILABLE_TYPE_IN_2_74 GLIB_UNAVAILABLE_TYPE(2, 74) ++#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_72 ++# define GLIB_AVAILABLE_IN_2_74 GLIB_UNAVAILABLE(2, 72) ++# define GLIB_AVAILABLE_STATIC_INLINE_IN_2_74 GLIB_UNAVAILABLE_STATIC_INLINE(2, 72) ++# define GLIB_AVAILABLE_MACRO_IN_2_74 GLIB_UNAVAILABLE_MACRO(2, 72) ++# define GLIB_AVAILABLE_ENUMERATOR_IN_2_74 GLIB_UNAVAILABLE_ENUMERATOR(2, 72) ++# define GLIB_AVAILABLE_TYPE_IN_2_74 GLIB_UNAVAILABLE_TYPE(2, 72) +#else +# define GLIB_AVAILABLE_IN_2_74 _GLIB_EXTERN +# define GLIB_AVAILABLE_STATIC_INLINE_IN_2_74 diff --git a/backport-gmessages-fix-dropping-irrelevant-log-domains.patch b/backport-gmessages-fix-dropping-irrelevant-log-domains.patch new file mode 100644 index 0000000..a92864a --- /dev/null +++ b/backport-gmessages-fix-dropping-irrelevant-log-domains.patch @@ -0,0 +1,128 @@ +From 71f6d4c129fc729a5ead08637924d8c0973f2fe9 Mon Sep 17 00:00:00 2001 +From: Alexander Slobodeniuk +Date: Wed, 1 Nov 2023 10:32:27 +0100 +Subject: [PATCH 1/2] gmessages: fix dropping irrelevant log domains + +If the string of one log domain is contained in +another, it was printing both. + +For example, if G_MESSAGES_DEBUG is "Gtkspecial", +it would also keep the logs of the "Gtk" domain + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/71f6d4c129fc729a5ead08637924d8c0973f2fe9 + +--- + glib/gmessages.c | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +diff --git a/glib/gmessages.c b/glib/gmessages.c +index d0d38c925a..ebd3a5433e 100644 +--- a/glib/gmessages.c ++++ b/glib/gmessages.c +@@ -2465,6 +2465,26 @@ log_is_old_api (const GLogField *fields, + g_strcmp0 (fields[0].value, "1") == 0); + } + ++static gboolean ++domain_found (const gchar *domains, ++ const char *log_domain) ++{ ++ guint len; ++ const gchar *found; ++ ++ len = strlen (log_domain); ++ ++ for (found = strstr (domains, log_domain); found; ++ found = strstr (found + 1, log_domain)) ++ { ++ if ((found == domains || found[-1] == ' ') ++ && (found[len] == 0 || found[len] == ' ')) ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ + /* + * Internal version of g_log_writer_default_would_drop(), which can + * read from either a log_domain or an array of fields. This avoids +@@ -2504,7 +2524,7 @@ should_drop_message (GLogLevelFlags log_level, + } + + if (strcmp (domains, "all") != 0 && +- (log_domain == NULL || !strstr (domains, log_domain))) ++ (log_domain == NULL || !domain_found (domains, log_domain))) + return TRUE; + } + +-- +GitLab + + +From 8eddbb9832b9a52a7495cc380e53715d920bb9ea Mon Sep 17 00:00:00 2001 +From: Alexander Slobodeniuk +Date: Wed, 1 Nov 2023 19:23:35 +0100 +Subject: [PATCH 2/2] glib/tests: extend logging test (dropping domains) + + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/8eddbb9832b9a52a7495cc380e53715d920bb9ea + +--- + glib/tests/logging.c | 40 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +diff --git a/glib/tests/logging.c b/glib/tests/logging.c +index ea9dcb825e..f4c47e16c8 100644 +--- a/glib/tests/logging.c ++++ b/glib/tests/logging.c +@@ -244,6 +244,46 @@ test_default_handler_would_drop (void) + g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo")); + g_assert_false (g_log_writer_default_would_drop (1< +Date: Sun, 20 Aug 2023 16:33:53 +0200 +Subject: [PATCH 1/2] gregex: if JIT stack limit is reached, fall back to + interpretive matching + +Conflict:Move large_test_string to fix declaration-after-statement +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/406f85a48f1ec41cda15ae617a979f7df749cb27 + +--- + glib/gregex.c | 13 ++++++++++--- + glib/tests/regex.c | 10 +++++++++- + 2 files changed, 19 insertions(+), 4 deletions(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index 5ce034db41..1b3ee02f30 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -484,8 +484,6 @@ translate_match_error (gint errcode) + /* not used by pcre2_match() */ + break; + case PCRE2_ERROR_MATCHLIMIT: +- case PCRE2_ERROR_JIT_STACKLIMIT: +- return _("backtracking limit reached"); + case PCRE2_ERROR_CALLOUT: + /* callouts are not implemented */ + break; +@@ -1107,8 +1105,17 @@ g_match_info_next (GMatchInfo *match_info, + opts, + match_info->match_data, + match_info->match_context); ++ /* if the JIT stack limit was reached, fall back to non-JIT matching in ++ * the next conditional statement */ ++ if (match_info->matches == PCRE2_ERROR_JIT_STACKLIMIT) ++ { ++ g_info ("PCRE2 JIT stack limit reached, falling back to " ++ "non-optimized matching."); ++ opts |= PCRE2_NO_JIT; ++ jit_status = JIT_STATUS_DISABLED; ++ } + } +- else ++ if (jit_status != JIT_STATUS_ENABLED) + { + match_info->matches = pcre2_match (match_info->regex->pcre_re, + (PCRE2_SPTR8) match_info->string, +diff --git a/glib/tests/regex.c b/glib/tests/regex.c +index 821fc59608..f18db483c2 100644 +--- a/glib/tests/regex.c ++++ b/glib/tests/regex.c +@@ -51,8 +51,9 @@ + /* A random value use to mark untouched integer variables. */ + #define UNTOUCHED -559038737 + +-/* A length of the test string in JIT stack test */ ++/* Lengths of test strings in JIT stack tests */ + #define TEST_STRING_LEN 20000 ++#define LARGE_TEST_STRING_LEN 200000 + + static gint total; + +@@ -2485,6 +2486,7 @@ int + main (int argc, char *argv[]) + { + char test_string[TEST_STRING_LEN]; ++ char large_test_string[LARGE_TEST_STRING_LEN]; + setlocale (LC_ALL, ""); + + g_test_init (&argc, &argv, NULL); +@@ -2711,6 +2713,12 @@ G_GNUC_END_IGNORE_DEPRECATIONS + test_string[TEST_STRING_LEN - 1] = '\0'; + TEST_MATCH_SIMPLE ("^(?:[ \t\n]|[^[:cntrl:]])*$", test_string, 0, 0, TRUE); + ++ /* Test that gregex falls back to unoptimized matching when reaching the JIT ++ * compiler stack limit */ ++ memset (large_test_string, '*', LARGE_TEST_STRING_LEN); ++ large_test_string[LARGE_TEST_STRING_LEN - 1] = '\0'; ++ TEST_MATCH_SIMPLE ("^(?:[ \t\n]|[^[:cntrl:]])*$", large_test_string, 0, 0, TRUE); ++ + /* TEST_MATCH(pattern, compile_opts, match_opts, string, + * string_len, start_position, match_opts2, expected) */ + TEST_MATCH("a", 0, 0, "a", -1, 0, 0, TRUE); +-- +GitLab + + +From 986fa3fdad5155924b17dbde16811d017a6413da Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Mon, 21 Aug 2023 10:19:43 +0000 +Subject: [PATCH 2/2] Apply 2 suggestion(s) to 1 file(s) + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/986fa3fdad5155924b17dbde16811d017a6413da + +--- + glib/gregex.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index 1b3ee02f30..b37a5e04c7 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -1109,12 +1109,13 @@ g_match_info_next (GMatchInfo *match_info, + * the next conditional statement */ + if (match_info->matches == PCRE2_ERROR_JIT_STACKLIMIT) + { +- g_info ("PCRE2 JIT stack limit reached, falling back to " +- "non-optimized matching."); ++ g_debug ("PCRE2 JIT stack limit reached, falling back to " ++ "non-optimized matching."); + opts |= PCRE2_NO_JIT; + jit_status = JIT_STATUS_DISABLED; + } + } ++ + if (jit_status != JIT_STATUS_ENABLED) + { + match_info->matches = pcre2_match (match_info->regex->pcre_re, +-- +GitLab \ No newline at end of file diff --git a/backport-gregex-set-default-max-stack-size-for-PCRE2-JIT-compiler-to-512KiB.patch b/backport-gregex-set-default-max-stack-size-for-PCRE2-JIT-compiler-to-512KiB.patch new file mode 100644 index 0000000..e9e88bc --- /dev/null +++ b/backport-gregex-set-default-max-stack-size-for-PCRE2-JIT-compiler-to-512KiB.patch @@ -0,0 +1,166 @@ +From 842a105464f6390a433da8791d7b19b65df16f47 Mon Sep 17 00:00:00 2001 +From: Aleksei Rybalkin +Date: Mon, 14 Aug 2023 20:32:48 +0200 +Subject: [PATCH 1/2] gregex: remove redundant call to + enable_jit_with_match_options + +There is no point to enable jit in g_regex_new, since JIT will be only +used when we do a first match, and at that point +enable_jit_with_match_options will be called again already and will +update the options set in g_regex_new. Instead just run it at first +match for the first time, to the same end result. + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/842a105464f6390a433da8791d7b19b65df16f47 + +--- + glib/gregex.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index 39b9edeecd..f6b2b716fc 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -1764,7 +1764,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS + regex->orig_compile_opts = compile_options; + regex->match_opts = pcre_match_options; + regex->orig_match_opts = match_options; +- regex->jit_status = enable_jit_with_match_options (regex, regex->match_opts); + + return regex; + } +-- +GitLab + + +From c3ff5b8eb39f1ab31383604910ae12f325e5afee Mon Sep 17 00:00:00 2001 +From: Aleksei Rybalkin +Date: Mon, 14 Aug 2023 20:41:40 +0200 +Subject: [PATCH 2/2] gregex: set default max stack size for PCRE2 JIT compiler + to 512KiB + +Previous default used was 32KiB (the library default) which caused some +complex patterns to fail, see #2824. The memory will not be allocated +unless used. + +Conflict:Move test_string to fix declaration-after-statement +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/c3ff5b8eb39f1ab31383604910ae12f325e5afee + +--- + glib/gregex.c | 22 ++++++++++++++-------- + glib/tests/regex.c | 9 +++++++++ + 2 files changed, 23 insertions(+), 8 deletions(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index f6b2b716fc..5ce034db41 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -232,6 +232,7 @@ struct _GMatchInfo + gssize string_len; /* length of string, in bytes */ + pcre2_match_context *match_context; + pcre2_match_data *match_data; ++ pcre2_jit_stack *jit_stack; + }; + + typedef enum +@@ -896,22 +897,22 @@ recalc_match_offsets (GMatchInfo *match_info, + } + + static JITStatus +-enable_jit_with_match_options (GRegex *regex, ++enable_jit_with_match_options (GMatchInfo *match_info, + uint32_t match_options) + { + gint retval; + uint32_t old_jit_options, new_jit_options; + +- if (!(regex->orig_compile_opts & G_REGEX_OPTIMIZE)) ++ if (!(match_info->regex->orig_compile_opts & G_REGEX_OPTIMIZE)) + return JIT_STATUS_DISABLED; + +- if (regex->jit_status == JIT_STATUS_DISABLED) ++ if (match_info->regex->jit_status == JIT_STATUS_DISABLED) + return JIT_STATUS_DISABLED; + + if (match_options & G_REGEX_PCRE2_JIT_UNSUPPORTED_OPTIONS) + return JIT_STATUS_DISABLED; + +- old_jit_options = regex->jit_options; ++ old_jit_options = match_info->regex->jit_options; + new_jit_options = old_jit_options | PCRE2_JIT_COMPLETE; + if (match_options & PCRE2_PARTIAL_HARD) + new_jit_options |= PCRE2_JIT_PARTIAL_HARD; +@@ -920,13 +921,16 @@ enable_jit_with_match_options (GRegex *regex, + + /* no new options enabled */ + if (new_jit_options == old_jit_options) +- return regex->jit_status; ++ return match_info->regex->jit_status; + +- retval = pcre2_jit_compile (regex->pcre_re, new_jit_options); ++ retval = pcre2_jit_compile (match_info->regex->pcre_re, new_jit_options); + switch (retval) + { + case 0: /* JIT enabled successfully */ +- regex->jit_options = new_jit_options; ++ match_info->regex->jit_options = new_jit_options; ++ /* Set min stack size for JIT to 32KiB and max to 512KiB */ ++ match_info->jit_stack = pcre2_jit_stack_create (1 << 15, 1 << 19, NULL); ++ pcre2_jit_stack_assign (match_info->match_context, NULL, match_info->jit_stack); + return JIT_STATUS_ENABLED; + case PCRE2_ERROR_NOMEMORY: + g_debug ("JIT compilation was requested with G_REGEX_OPTIMIZE, " +@@ -1023,6 +1027,8 @@ g_match_info_unref (GMatchInfo *match_info) + g_regex_unref (match_info->regex); + if (match_info->match_context) + pcre2_match_context_free (match_info->match_context); ++ if (match_info->jit_stack) ++ pcre2_jit_stack_free (match_info->jit_stack); + if (match_info->match_data) + pcre2_match_data_free (match_info->match_data); + g_free (match_info->offsets); +@@ -1091,7 +1097,7 @@ g_match_info_next (GMatchInfo *match_info, + + opts = match_info->regex->match_opts | match_info->match_opts; + +- jit_status = enable_jit_with_match_options (match_info->regex, opts); ++ jit_status = enable_jit_with_match_options (match_info, opts); + if (jit_status == JIT_STATUS_ENABLED) + { + match_info->matches = pcre2_jit_match (match_info->regex->pcre_re, +diff --git a/glib/tests/regex.c b/glib/tests/regex.c +index cf2bb8199d..821fc59608 100644 +--- a/glib/tests/regex.c ++++ b/glib/tests/regex.c +@@ -51,6 +51,9 @@ + /* A random value use to mark untouched integer variables. */ + #define UNTOUCHED -559038737 + ++/* A length of the test string in JIT stack test */ ++#define TEST_STRING_LEN 20000 ++ + static gint total; + + typedef struct { +@@ -2481,6 +2484,7 @@ test_jit_unsupported_matching_options (void) + int + main (int argc, char *argv[]) + { ++ char test_string[TEST_STRING_LEN]; + setlocale (LC_ALL, ""); + + g_test_init (&argc, &argv, NULL); +@@ -2702,6 +2706,11 @@ G_GNUC_END_IGNORE_DEPRECATIONS + TEST_MATCH_SIMPLE("\\", "a", 0, 0, FALSE); + TEST_MATCH_SIMPLE("[", "", 0, 0, FALSE); + ++ /* Test that JIT compiler has enough stack */ ++ memset (test_string, '*', TEST_STRING_LEN); ++ test_string[TEST_STRING_LEN - 1] = '\0'; ++ TEST_MATCH_SIMPLE ("^(?:[ \t\n]|[^[:cntrl:]])*$", test_string, 0, 0, TRUE); ++ + /* TEST_MATCH(pattern, compile_opts, match_opts, string, + * string_len, start_position, match_opts2, expected) */ + TEST_MATCH("a", 0, 0, "a", -1, 0, 0, TRUE); +-- +GitLab \ No newline at end of file diff --git a/backport-gutils-Fix-an-unlikely-minor-leak-in-g_build_user_data_dir.patch b/backport-gutils-Fix-an-unlikely-minor-leak-in-g_build_user_data_dir.patch new file mode 100644 index 0000000..9a3fc8e --- /dev/null +++ b/backport-gutils-Fix-an-unlikely-minor-leak-in-g_build_user_data_dir.patch @@ -0,0 +1,31 @@ +From 1a979ab4947fc259af01ea65263aaa4d417553fb Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Tue, 14 Nov 2023 11:00:21 +0000 +Subject: [PATCH] gutils: Fix an unlikely minor leak in g_build_user_data_dir() + +A leak can happen if the `data_dir` is the empty string. + +See https://gitlab.gnome.org/GNOME/glib/-/jobs/3294034 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/1a979ab4947fc259af01ea65263aaa4d417553fb + +Signed-off-by: Philip Withnall +--- + glib/gutils.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/glib/gutils.c b/glib/gutils.c +index dfe115843e..ffc7d750c7 100644 +--- a/glib/gutils.c ++++ b/glib/gutils.c +@@ -1883,6 +1883,7 @@ g_build_user_data_dir (void) + if (!data_dir || !data_dir[0]) + { + gchar *home_dir = g_build_home_dir (); ++ g_free (data_dir); + data_dir = g_build_filename (home_dir, ".local", "share", NULL); + g_free (home_dir); + } +-- +GitLab \ No newline at end of file diff --git a/glib2.spec b/glib2.spec index 6e26bbf..9e20f56 100644 --- a/glib2.spec +++ b/glib2.spec @@ -1,6 +1,6 @@ Name: glib2 Version: 2.72.2 -Release: 12 +Release: 13 Summary: The core library that forms the basis for projects such as GTK+ and GNOME License: LGPLv2+ URL: http://www.gtk.org @@ -71,6 +71,12 @@ patch6061: backport-glocalfilemonitor-Avoid-file-monitor-destruction-from-e patch6062: backport-glocalfilemonitor-Skip-event-handling-if-the-source-has-been-destroyed.patch patch6063: backport-tests-Add-a-test-for-GFileMonitor-deadlocks.patch +Patch6064: backport-gregex-set-default-max-stack-size-for-PCRE2-JIT-compiler-to-512KiB.patch +Patch6065: backport-gregex-if-JIT-stack-limit-is-reached-fall-back-to-interpretive-matching.patch +Patch6066: backport-Make-sure-the-GTask-is-freed-on-a-graceful-disconnect.patch +Patch6067: backport-gmessages-fix-dropping-irrelevant-log-domains.patch +Patch6068: backport-gutils-Fix-an-unlikely-minor-leak-in-g_build_user_data_dir.patch + BuildRequires: chrpath gcc gcc-c++ gettext perl-interpreter BUildRequires: glibc-devel libattr-devel libselinux-devel meson BuildRequires: systemtap-sdt-devel pkgconfig(libelf) pkgconfig(libffi) @@ -265,6 +271,9 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : %endif %changelog +* Thu Jan 11 2024 hanhuihui - 2.72.2-13 +- fix pcre2 error , memory leak and log domains error + * Mon Sep 25 2023 liningjie - 2.72.2-12 - glocalfilemonitor: Avoid file monitor destruction from event thread -- Gitee