From d7844cb1be62a55737bb823f423c4af2beefb6cf Mon Sep 17 00:00:00 2001 From: Hiroshi Hatake Date: Mon, 22 Jun 2026 15:11:13 +0900 Subject: [PATCH 1/2] scheduler: Dispose ch_events on destroy Signed-off-by: Hiroshi Hatake --- src/flb_scheduler.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/flb_scheduler.c b/src/flb_scheduler.c index d4fa442e9ae..d966f492b87 100644 --- a/src/flb_scheduler.c +++ b/src/flb_scheduler.c @@ -751,6 +751,9 @@ struct flb_sched *flb_sched_create(struct flb_config *config, sched->config = config; sched->evl = evl; + sched->ch_events[0] = -1; + sched->ch_events[1] = -1; + MK_EVENT_ZERO(&sched->event); /* Initialize lists */ mk_list_init(&sched->requests); @@ -791,7 +794,7 @@ struct flb_sched *flb_sched_create(struct flb_config *config, ret = mk_event_channel_create(sched->evl, &sched->ch_events[0], &sched->ch_events[1], - sched); + &sched->event); if (ret == -1) { flb_sched_destroy(sched); return NULL; @@ -849,6 +852,15 @@ int flb_sched_destroy(struct flb_sched *sched) c++; } + if (sched->ch_events[0] != -1) { + mk_event_channel_destroy(sched->evl, + sched->ch_events[0], + sched->ch_events[1], + &sched->event); + sched->ch_events[0] = -1; + sched->ch_events[1] = -1; + } + flb_free(sched); return c; } From 29c102fc9a735085f646a0193a011d5748dcbc12 Mon Sep 17 00:00:00 2001 From: Hiroshi Hatake Date: Mon, 22 Jun 2026 15:11:52 +0900 Subject: [PATCH 2/2] tests: internal: Add a test case for disposing scheduler cleanly Signed-off-by: Hiroshi Hatake --- tests/internal/CMakeLists.txt | 1 + tests/internal/scheduler.c | 110 ++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 tests/internal/scheduler.c diff --git a/tests/internal/CMakeLists.txt b/tests/internal/CMakeLists.txt index 9f01fc93b26..6ce01a29332 100644 --- a/tests/internal/CMakeLists.txt +++ b/tests/internal/CMakeLists.txt @@ -37,6 +37,7 @@ set(UNIT_TESTS_FILES flb_event_loop.c ring_buffer.c regex.c + scheduler.c parser_json.c parser_ltsv.c parser_regex.c diff --git a/tests/internal/scheduler.c b/tests/internal/scheduler.c new file mode 100644 index 00000000000..90210b44de3 --- /dev/null +++ b/tests/internal/scheduler.c @@ -0,0 +1,110 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* Fluent Bit + * ========== + * Copyright (C) 2015-2026 The Fluent Bit Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "flb_tests_internal.h" + +static void test_scheduler_event_channel_cleanup(void) +{ + int ret; + char data = '\0'; + flb_pipefd_t read_fd[2]; + flb_pipefd_t write_fd[2]; + struct flb_sched *sched[2]; + struct flb_config *config; + struct mk_event_loop *evl; +#ifdef FLB_SYSTEM_WINDOWS + WSADATA wsa_data; + + ret = WSAStartup(MAKEWORD(2, 2), &wsa_data); + if (!TEST_CHECK(ret == 0)) { + return; + } +#endif + + config = flb_config_init(); + if (!TEST_CHECK(config != NULL)) { + goto socket_cleanup; + } + + config->evl = mk_event_loop_create(8); + if (!TEST_CHECK(config->evl != NULL)) { + flb_config_exit(config); + goto socket_cleanup; + } + + sched[0] = flb_sched_create(config, config->evl); + if (!TEST_CHECK(sched[0] != NULL)) { + flb_config_exit(config); + goto socket_cleanup; + } + config->sched = sched[0]; + + evl = mk_event_loop_create(8); + if (!TEST_CHECK(evl != NULL)) { + flb_config_exit(config); + goto socket_cleanup; + } + + sched[1] = flb_sched_create(config, evl); + if (!TEST_CHECK(sched[1] != NULL)) { + mk_event_loop_destroy(evl); + flb_config_exit(config); + goto socket_cleanup; + } + + read_fd[0] = sched[0]->ch_events[0]; + write_fd[0] = sched[0]->ch_events[1]; + read_fd[1] = sched[1]->ch_events[0]; + write_fd[1] = sched[1]->ch_events[1]; + + flb_sched_destroy(sched[1]); + mk_event_loop_destroy(evl); + + flb_sched_destroy(sched[0]); + config->sched = NULL; + + ret = flb_pipe_w(write_fd[0], &data, sizeof(data)); + TEST_CHECK(ret == -1); + + ret = flb_pipe_r(read_fd[0], &data, sizeof(data)); + TEST_CHECK(ret == -1); + + ret = flb_pipe_w(write_fd[1], &data, sizeof(data)); + TEST_CHECK(ret == -1); + + ret = flb_pipe_r(read_fd[1], &data, sizeof(data)); + TEST_CHECK(ret == -1); + + flb_config_exit(config); + +socket_cleanup: + (void) ret; +#ifdef FLB_SYSTEM_WINDOWS + WSACleanup(); +#endif +} + +TEST_LIST = { + {"event_channel_cleanup", test_scheduler_event_channel_cleanup}, + {NULL, NULL} +};