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) {

Reply via email to