From 0eeb5a3b586a1caed724ce93be39749c0eaf58ee Mon Sep 17 00:00:00 2001 From: Minggang Wang Date: Thu, 15 Jan 2026 13:17:48 +0800 Subject: [PATCH 1/2] Fix race condition causing crash when setting content filter during spin --- src/rcl_subscription_bindings.cpp | 10 +++++++--- test/test-subscription-content-filter.js | 8 ++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/rcl_subscription_bindings.cpp b/src/rcl_subscription_bindings.cpp index 78bcd333..06f2f30a 100644 --- a/src/rcl_subscription_bindings.cpp +++ b/src/rcl_subscription_bindings.cpp @@ -283,18 +283,22 @@ Napi::Value SetContentFilter(const Napi::CallbackInfo& info) { free(argv); } + std::string error_string; + if (ret != RCL_RET_OK) { + error_string = rcl_get_error_string().str; + rcl_reset_error(); + } + rcl_ret_t fini_ret = rcl_subscription_content_filter_options_fini(subscription, &options); if (ret != RCL_RET_OK) { - std::string error_string = rcl_get_error_string().str; - rcl_reset_error(); Napi::Error::New(env, error_string).ThrowAsJavaScriptException(); return env.Undefined(); } if (fini_ret != RCL_RET_OK) { - std::string error_string = rcl_get_error_string().str; + error_string = rcl_get_error_string().str; rcl_reset_error(); Napi::Error::New(env, error_string).ThrowAsJavaScriptException(); return env.Undefined(); diff --git a/test/test-subscription-content-filter.js b/test/test-subscription-content-filter.js index 5660324a..4d58f651 100644 --- a/test/test-subscription-content-filter.js +++ b/test/test-subscription-content-filter.js @@ -295,7 +295,10 @@ describe('subscription content-filtering', function () { const contentFilter5 = { expression: 'data = 5', }; + // Stop spinning before changing content filter to avoid race condition + this.subscriberNode.stop(); subscription.setContentFilter(contentFilter5); + this.subscriberNode.spin(); resolve(msgCnt); }, SUBSCRIBER_WAIT_TIME) ); @@ -304,6 +307,7 @@ describe('subscription content-filtering', function () { const p2 = new Promise((resolve) => setTimeout(() => { + this.subscriberNode.stop(); resolve(!fail && msgCnt5 && !msgCnt0); }, SUBSCRIBER_WAIT_TIME) ); @@ -364,7 +368,10 @@ describe('subscription content-filtering', function () { const p1 = new Promise((resolve) => setTimeout(() => { const result = !msgCnt0 && msgCnt5 && !fail; + // Stop spinning before changing content filter to avoid race condition + this.subscriberNode.stop(); subscription.setContentFilter(); + this.subscriberNode.spin(); resolve(result); }, SUBSCRIBER_WAIT_TIME) ); @@ -374,6 +381,7 @@ describe('subscription content-filtering', function () { const p2 = new Promise((resolve) => setTimeout(() => { + this.subscriberNode.stop(); resolve(msgCnt0 && msgCnt5 && !fail); }, SUBSCRIBER_WAIT_TIME) ); From 1de4f4b9fbe06f8b953b91beca9988ae28c3d7d3 Mon Sep 17 00:00:00 2001 From: Minggang Wang Date: Thu, 15 Jan 2026 13:57:48 +0800 Subject: [PATCH 2/2] Address comments --- src/rcl_subscription_bindings.cpp | 2 +- test/test-subscription-content-filter.js | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/rcl_subscription_bindings.cpp b/src/rcl_subscription_bindings.cpp index 06f2f30a..2f5ee251 100644 --- a/src/rcl_subscription_bindings.cpp +++ b/src/rcl_subscription_bindings.cpp @@ -283,7 +283,7 @@ Napi::Value SetContentFilter(const Napi::CallbackInfo& info) { free(argv); } - std::string error_string; + std::string error_string = ""; if (ret != RCL_RET_OK) { error_string = rcl_get_error_string().str; rcl_reset_error(); diff --git a/test/test-subscription-content-filter.js b/test/test-subscription-content-filter.js index 4d58f651..099b4ae1 100644 --- a/test/test-subscription-content-filter.js +++ b/test/test-subscription-content-filter.js @@ -307,7 +307,6 @@ describe('subscription content-filtering', function () { const p2 = new Promise((resolve) => setTimeout(() => { - this.subscriberNode.stop(); resolve(!fail && msgCnt5 && !msgCnt0); }, SUBSCRIBER_WAIT_TIME) ); @@ -381,7 +380,6 @@ describe('subscription content-filtering', function () { const p2 = new Promise((resolve) => setTimeout(() => { - this.subscriberNode.stop(); resolve(msgCnt0 && msgCnt5 && !fail); }, SUBSCRIBER_WAIT_TIME) );