This is an automated email from the ASF dual-hosted git repository. pengzheng pushed a commit to branch hotfix/629-deadlock-of-test_fshelltestsuite-quittest in repository https://gitbox.apache.org/repos/asf/celix.git
The following commit(s) were added to refs/heads/hotfix/629-deadlock-of-test_fshelltestsuite-quittest by this push: new 4e6c5b4f Update shell test to avoid potential deadlock 4e6c5b4f is described below commit 4e6c5b4f607ad6caab2e2971fc327e8a38178885 Author: PengZheng <howto...@gmail.com> AuthorDate: Sun Sep 3 20:21:21 2023 +0800 Update shell test to avoid potential deadlock This change resolves the potential deadlock issue (#629) when calling quit/stop commands. celix_bundleContext_trackService is utilized instead of the old `celix_bundleContext_useServiceWithOptions` method. --- bundles/shell/shell/gtest/src/ShellTestSuite.cc | 26 +++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/bundles/shell/shell/gtest/src/ShellTestSuite.cc b/bundles/shell/shell/gtest/src/ShellTestSuite.cc index 6f85f70d..8c43e016 100644 --- a/bundles/shell/shell/gtest/src/ShellTestSuite.cc +++ b/bundles/shell/shell/gtest/src/ShellTestSuite.cc @@ -17,6 +17,7 @@ * under the License. */ +#include <future> #include <gtest/gtest.h> #include <thread> @@ -63,20 +64,24 @@ TEST_F(ShellTestSuite, shellBundleInstalledTest) { } static void callCommand(std::shared_ptr<celix_bundle_context_t>& ctx, const char *cmdLine, bool cmdShouldSucceed) { - celix_service_use_options_t opts{}; - struct callback_data { const char *cmdLine{}; bool cmdShouldSucceed{}; + std::promise<void> barrier{}; + celix_bundle_context_t* context{}; + long tracker{-1}; }; + // Note that using celix_bundleContext_useServiceWithOptions to call command quit/stop may result in deadlock. + // For more on this, see https://github.com/apache/celix/issues/629 struct callback_data data{}; data.cmdLine = cmdLine; data.cmdShouldSucceed = cmdShouldSucceed; - - opts.filter.serviceName = CELIX_SHELL_SERVICE_NAME; - opts.callbackHandle = static_cast<void*>(&data); - opts.waitTimeoutInSeconds = 1.0; - opts.use = [](void *handle, void *svc) { + data.context = ctx.get(); + data.tracker = celix_bundleContext_trackService(ctx.get(), CELIX_SHELL_SERVICE_NAME, + static_cast<void*>(&data), [](void * handle, void * svc) { + if (svc == nullptr) { + return; + } auto *shell = static_cast<celix_shell_t *>(svc); auto *d = static_cast<struct callback_data*>(handle); EXPECT_TRUE(shell != nullptr); @@ -86,9 +91,10 @@ static void callCommand(std::shared_ptr<celix_bundle_context_t>& ctx, const char } else { EXPECT_NE(CELIX_SUCCESS, status) << "Command '" << d->cmdLine << "' should not succeed"; } - }; - bool called = celix_bundleContext_useServiceWithOptions(ctx.get(), &opts); - EXPECT_TRUE(called); + celix_bundleContext_stopTracker(d->context, d->tracker); + d->barrier.set_value(); + }); + data.barrier.get_future().wait(); } TEST_F(ShellTestSuite, testAllCommandsAreCallable) {