You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2021/08/08 12:31:11 UTC

[celix] branch hotfix/alias_and_ci_issues created (now 509a773)

This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a change to branch hotfix/alias_and_ci_issues
in repository https://gitbox.apache.org/repos/asf/celix.git.


      at 509a773  Fixes an issue in the celix_bundleContext_useService(s) which lead to deadlocks

This branch includes the following new commits:

     new 8d0ce27  Removes use of cmake target alias in CelixConfig.
     new 509a773  Fixes an issue in the celix_bundleContext_useService(s) which lead to deadlocks

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[celix] 01/02: Removes use of cmake target alias in CelixConfig.

Posted by pn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch hotfix/alias_and_ci_issues
in repository https://gitbox.apache.org/repos/asf/celix.git

commit 8d0ce27f2c8a2bafd10c5573a87435e41e02cf8d
Author: Pepijn Noltes <pe...@gmail.com>
AuthorDate: Sun Aug 8 14:29:21 2021 +0200

    Removes use of cmake target alias in CelixConfig.
---
 bundles/pubsub/CMakeLists.txt                        |  6 +++---
 bundles/pubsub/pubsub_admin_tcp/v1/CMakeLists.txt    | 20 ++++++++++----------
 .../pubsub/pubsub_admin_websocket/v1/CMakeLists.txt  | 18 +++++++++---------
 bundles/pubsub/pubsub_admin_zmq/v1/CMakeLists.txt    | 18 +++++++++---------
 cmake/CelixConfig.cmake                              | 11 -----------
 5 files changed, 31 insertions(+), 42 deletions(-)

diff --git a/bundles/pubsub/CMakeLists.txt b/bundles/pubsub/CMakeLists.txt
index 01d2140..39c04b2 100644
--- a/bundles/pubsub/CMakeLists.txt
+++ b/bundles/pubsub/CMakeLists.txt
@@ -23,14 +23,14 @@ if (PUBSUB)
         option(BUILD_ZMQ_SECURITY "Build with security for ZeroMQ." OFF)
         add_subdirectory(pubsub_admin_zmq/v1)
         add_subdirectory(pubsub_admin_zmq/v2)
-        add_library(Celix::celix_pubsub_admin_zmq ALIAS celix_pubsub_admin_zmq_v1)
+        add_library(Celix::celix_pubsub_admin_zmq ALIAS celix_pubsub_admin_zmq)
     endif (BUILD_PUBSUB_PSA_ZMQ)
 
     option(BUILD_PUBSUB_PSA_TCP "Build TCP PubSub Admin" ON)
     if (BUILD_PUBSUB_PSA_TCP)
         add_subdirectory(pubsub_admin_tcp/v1)
         add_subdirectory(pubsub_admin_tcp/v2)
-        add_library(Celix::celix_pubsub_admin_tcp ALIAS celix_pubsub_admin_tcp_v1)
+        add_library(Celix::celix_pubsub_admin_tcp ALIAS celix_pubsub_admin_tcp)
     endif (BUILD_PUBSUB_PSA_TCP)
 
     option(BUILD_PUBSUB_PSA_UDP_MC "Build UDP MC PubSub Admin" ON)
@@ -42,7 +42,7 @@ if (PUBSUB)
     if (BUILD_PUBSUB_PSA_WS)
         add_subdirectory(pubsub_admin_websocket/v1)
         add_subdirectory(pubsub_admin_websocket/v2)
-        add_library(Celix::celix_pubsub_admin_websocket ALIAS celix_pubsub_admin_websocket_v1)
+        add_library(Celix::celix_pubsub_admin_websocket ALIAS celix_pubsub_admin_websocket)
     endif (BUILD_PUBSUB_PSA_WS)
 
     add_subdirectory(pubsub_api)
diff --git a/bundles/pubsub/pubsub_admin_tcp/v1/CMakeLists.txt b/bundles/pubsub/pubsub_admin_tcp/v1/CMakeLists.txt
index 8039b77..9a181eb 100644
--- a/bundles/pubsub/pubsub_admin_tcp/v1/CMakeLists.txt
+++ b/bundles/pubsub/pubsub_admin_tcp/v1/CMakeLists.txt
@@ -19,8 +19,8 @@ message(STATUS "PubSub TCP Admin V1 is deprecated, and will eventually be replac
 
 find_package(UUID REQUIRED)
 
-add_celix_bundle(celix_pubsub_admin_tcp_v1
-    BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_tcp_v1"
+add_celix_bundle(celix_pubsub_admin_tcp
+    BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_tcp"
     VERSION "1.0.0"
     GROUP "Celix/PubSub"
     SOURCES
@@ -32,15 +32,15 @@ add_celix_bundle(celix_pubsub_admin_tcp_v1
         src/pubsub_tcp_common.c
 )
 
-set_target_properties(celix_pubsub_admin_tcp_v1 PROPERTIES INSTALL_RPATH "$ORIGIN")
-target_link_libraries(celix_pubsub_admin_tcp_v1 PRIVATE Celix::pubsub_spi Celix::pubsub_utils)
-target_link_libraries(celix_pubsub_admin_tcp_v1 PRIVATE Celix::framework Celix::dfi Celix::log_helper)
-target_include_directories(celix_pubsub_admin_tcp_v1 PRIVATE src)
+set_target_properties(celix_pubsub_admin_tcp PROPERTIES INSTALL_RPATH "$ORIGIN")
+target_link_libraries(celix_pubsub_admin_tcp PRIVATE Celix::pubsub_spi Celix::pubsub_utils)
+target_link_libraries(celix_pubsub_admin_tcp PRIVATE Celix::framework Celix::dfi Celix::log_helper)
+target_include_directories(celix_pubsub_admin_tcp PRIVATE src)
 # cmake find package UUID set the wrong include dir for OSX
 if (NOT APPLE)
-    target_link_libraries(celix_pubsub_admin_tcp_v1 PRIVATE UUID::lib)
+    target_link_libraries(celix_pubsub_admin_tcp PRIVATE UUID::lib)
 endif()
 
-install_celix_bundle(celix_pubsub_admin_tcp_v1 EXPORT celix COMPONENT pubsub)
-target_link_libraries(celix_pubsub_admin_tcp_v1 PRIVATE Celix::shell_api)
-add_library(Celix::celix_pubsub_admin_tcp_v1 ALIAS celix_pubsub_admin_tcp_v1)
+install_celix_bundle(celix_pubsub_admin_tcp EXPORT celix COMPONENT pubsub)
+target_link_libraries(celix_pubsub_admin_tcp PRIVATE Celix::shell_api)
+add_library(Celix::celix_pubsub_admin_tcp ALIAS celix_pubsub_admin_tcp)
diff --git a/bundles/pubsub/pubsub_admin_websocket/v1/CMakeLists.txt b/bundles/pubsub/pubsub_admin_websocket/v1/CMakeLists.txt
index 4cff18f..a38ac85 100644
--- a/bundles/pubsub/pubsub_admin_websocket/v1/CMakeLists.txt
+++ b/bundles/pubsub/pubsub_admin_websocket/v1/CMakeLists.txt
@@ -20,8 +20,8 @@ message(STATUS "PubSub Websocket Admin V1 is deprecated, and will eventually be
 find_package(Jansson REQUIRED)
 find_package(UUID REQUIRED)
 
-add_celix_bundle(celix_pubsub_admin_websocket_v1
-    BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_websocket_v1"
+add_celix_bundle(celix_pubsub_admin_websocket
+    BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_websocket"
     VERSION "1.0.0"
     GROUP "Celix/PubSub"
     SOURCES
@@ -32,16 +32,16 @@ add_celix_bundle(celix_pubsub_admin_websocket_v1
         src/pubsub_websocket_common.c
 )
 
-set_target_properties(celix_pubsub_admin_websocket_v1 PROPERTIES INSTALL_RPATH "$ORIGIN")
-target_link_libraries(celix_pubsub_admin_websocket_v1 PRIVATE
+set_target_properties(celix_pubsub_admin_websocket PROPERTIES INSTALL_RPATH "$ORIGIN")
+target_link_libraries(celix_pubsub_admin_websocket PRIVATE
         Celix::framework Celix::dfi Celix::log_helper Celix::utils
         Celix::http_admin_api
 )
-target_link_libraries(celix_pubsub_admin_websocket_v1 PRIVATE Celix::pubsub_spi Celix::pubsub_utils )
-target_include_directories(celix_pubsub_admin_websocket_v1 PRIVATE
+target_link_libraries(celix_pubsub_admin_websocket PRIVATE Celix::pubsub_spi Celix::pubsub_utils )
+target_include_directories(celix_pubsub_admin_websocket PRIVATE
     src
 )
 
-install_celix_bundle(celix_pubsub_admin_websocket_v1 EXPORT celix COMPONENT pubsub)
-target_link_libraries(celix_pubsub_admin_websocket_v1 PRIVATE Celix::shell_api)
-add_library(Celix::celix_pubsub_admin_websocket_v1 ALIAS celix_pubsub_admin_websocket_v1)
+install_celix_bundle(celix_pubsub_admin_websocket EXPORT celix COMPONENT pubsub)
+target_link_libraries(celix_pubsub_admin_websocket PRIVATE Celix::shell_api)
+add_library(Celix::celix_pubsub_admin_websocket ALIAS celix_pubsub_admin_websocket)
diff --git a/bundles/pubsub/pubsub_admin_zmq/v1/CMakeLists.txt b/bundles/pubsub/pubsub_admin_zmq/v1/CMakeLists.txt
index 37ea629..2427425 100644
--- a/bundles/pubsub/pubsub_admin_zmq/v1/CMakeLists.txt
+++ b/bundles/pubsub/pubsub_admin_zmq/v1/CMakeLists.txt
@@ -33,8 +33,8 @@ if (BUILD_ZMQ_SECURITY)
     set (ZMQ_CRYPTO_C "src/zmq_crypto.c")
 endif()
 
-add_celix_bundle(celix_pubsub_admin_zmq_v1
-    BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_zmq_v1"
+add_celix_bundle(celix_pubsub_admin_zmq
+    BUNDLE_SYMBOLICNAME "apache_celix_pubsub_admin_zmq"
     VERSION "1.1.0"
     GROUP "Celix/PubSub"
     SOURCES
@@ -45,17 +45,17 @@ add_celix_bundle(celix_pubsub_admin_zmq_v1
         ${ZMQ_CRYPTO_C}
 )
 
-set_target_properties(celix_pubsub_admin_zmq_v1 PROPERTIES INSTALL_RPATH "$ORIGIN")
-target_link_libraries(celix_pubsub_admin_zmq_v1 PRIVATE
+set_target_properties(celix_pubsub_admin_zmq PROPERTIES INSTALL_RPATH "$ORIGIN")
+target_link_libraries(celix_pubsub_admin_zmq PRIVATE
 
         Celix::framework Celix::dfi Celix::log_helper Celix::utils
         ZMQ::lib CZMQ::lib ${OPTIONAL_OPENSSL_LIB}
 )
-target_link_libraries(celix_pubsub_admin_zmq_v1 PRIVATE Celix::pubsub_spi Celix::pubsub_utils )
-target_include_directories(celix_pubsub_admin_zmq_v1 PRIVATE
+target_link_libraries(celix_pubsub_admin_zmq PRIVATE Celix::pubsub_spi Celix::pubsub_utils )
+target_include_directories(celix_pubsub_admin_zmq PRIVATE
     src
 )
 
-install_celix_bundle(celix_pubsub_admin_zmq_v1 EXPORT celix COMPONENT pubsub)
-target_link_libraries(celix_pubsub_admin_zmq_v1 PRIVATE Celix::shell_api)
-add_library(Celix::celix_pubsub_admin_zmq_v1 ALIAS celix_pubsub_admin_zmq_v1)
+install_celix_bundle(celix_pubsub_admin_zmq EXPORT celix COMPONENT pubsub)
+target_link_libraries(celix_pubsub_admin_zmq PRIVATE Celix::shell_api)
+add_library(Celix::celix_pubsub_admin_zmq ALIAS celix_pubsub_admin_zmq)
diff --git a/cmake/CelixConfig.cmake b/cmake/CelixConfig.cmake
index a7e9f04..6c7acb4 100644
--- a/cmake/CelixConfig.cmake
+++ b/cmake/CelixConfig.cmake
@@ -68,17 +68,6 @@ if (TARGET Celix::dependency_manager_cxx)
   set(CELIX_DM_CXX_STATIC_LIB $<TARGET_PROPERTY:Celix::dependency_manager_cxx,INTERFACE_INCLUDE_DIRECTORIES>)
 endif ()
 
-#Setting up pubsub admin alias to the v1 version.
-if (TARGET Celix::celix_pubsub_admin_zmq_v1)
-  add_library(Celix::celix_pubsub_admin_zmq ALIAS Celix::celix_pubsub_admin_zmq_v1)
-endif ()
-if (TARGET Celix::celix_pubsub_admin_tcp_v1)
-  add_library(Celix::celix_pubsub_admin_tcp ALIAS Celix::celix_pubsub_admin_tcp_v1)
-endif ()
-if (TARGET Celix::celix_pubsub_admin_websocket_v1)
-  add_library(Celix::celix_pubsub_admin_websocket ALIAS Celix::celix_pubsub_admin_websocket_v1)
-endif ()
-
 set(CELIX_BUNDLES_DIR ${REL_INSTALL_DIR}/share/celix/bundles)
 set(CELIX_SHELL_BUNDLE ${CELIX_BUNDLES_DIR}/shell.zip)
 set(CELIX_SHELL_TUI_BUNDLE ${CELIX_BUNDLES_DIR}/shell_tui.zip)

[celix] 02/02: Fixes an issue in the celix_bundleContext_useService(s) which lead to deadlocks

Posted by pn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch hotfix/alias_and_ci_issues
in repository https://gitbox.apache.org/repos/asf/celix.git

commit 509a773c06c6d53da06e9ada0a2d294f43c25fe4
Author: Pepijn Noltes <pe...@gmail.com>
AuthorDate: Sun Aug 8 14:29:54 2021 +0200

    Fixes an issue in the celix_bundleContext_useService(s) which lead to deadlocks
---
 libs/framework/src/bundle_context.c | 69 +++++++++++++++++++++++++++----------
 1 file changed, 51 insertions(+), 18 deletions(-)

diff --git a/libs/framework/src/bundle_context.c b/libs/framework/src/bundle_context.c
index 8f64ec6..ae9b68f 100644
--- a/libs/framework/src/bundle_context.c
+++ b/libs/framework/src/bundle_context.c
@@ -1161,9 +1161,11 @@ size_t celix_bundleContext_useServices(
 
 typedef struct celix_bundle_context_use_service_data {
     celix_bundle_context_t* ctx;
-    celix_service_filter_options_t opts;
+    const celix_service_use_options_t* opts;
 
     celix_thread_mutex_t mutex; //protects below;
+    bool called; //for use service
+    size_t count; //for use services
     celix_service_tracker_t * svcTracker;
 } celix_bundle_context_use_service_data_t;
 
@@ -1172,14 +1174,25 @@ static void celix_bundleContext_useServiceWithOptions_1_CreateServiceTracker(voi
     assert(celix_framework_isCurrentThreadTheEventLoop(d->ctx->framework));
 
     celix_service_tracking_options_t trkOpts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
-    trkOpts.filter = d->opts;
+    trkOpts.filter = d->opts->filter;
 
     celixThreadMutex_lock(&d->mutex);
+    d->called = false;
+    d->count = 0;
     d->svcTracker = celix_serviceTracker_createWithOptions(d->ctx, &trkOpts);
     celixThreadMutex_unlock(&d->mutex);
 }
 
-static void celix_bundleContext_useServiceWithOptions_2_CloseServiceTracker(void *data) {
+static void celix_bundleContext_useServiceWithOptions_2_UseServiceTracker(void *data) {
+    celix_bundle_context_use_service_data_t* d = data;
+    assert(celix_framework_isCurrentThreadTheEventLoop(d->ctx->framework));
+
+    celixThreadMutex_lock(&d->mutex);
+    d->called = celix_serviceTracker_useHighestRankingService(d->svcTracker, d->opts->filter.serviceName, d->opts->callbackHandle, d->opts->use, d->opts->useWithProperties, d->opts->useWithOwner);
+    celixThreadMutex_unlock(&d->mutex);
+}
+
+static void celix_bundleContext_useServiceWithOptions_3_CloseServiceTracker(void *data) {
     celix_bundle_context_use_service_data_t* d = data;
     assert(celix_framework_isCurrentThreadTheEventLoop(d->ctx->framework));
 
@@ -1200,13 +1213,13 @@ bool celix_bundleContext_useServiceWithOptions(
 
     celix_bundle_context_use_service_data_t data = {0};
     data.ctx = ctx;
-    data.opts = opts->filter;
+    data.opts = opts;
     celixThreadMutex_create(&data.mutex, NULL);
 
     if (celix_framework_isCurrentThreadTheEventLoop(ctx->framework)) {
         celix_bundleContext_useServiceWithOptions_1_CreateServiceTracker(&data);
     } else {
-        long eventId = celix_framework_fireGenericEvent(ctx->framework, -1, celix_bundle_getId(ctx->bundle), "create service tracker for use service", &data, celix_bundleContext_useServiceWithOptions_1_CreateServiceTracker, NULL, NULL);
+        long eventId = celix_framework_fireGenericEvent(ctx->framework, -1, celix_bundle_getId(ctx->bundle), "create service tracker for celix_bundleContext_useServiceWithOptions", &data, celix_bundleContext_useServiceWithOptions_1_CreateServiceTracker, NULL, NULL);
         celix_framework_waitForGenericEvent(ctx->framework, eventId);
     }
 
@@ -1218,13 +1231,20 @@ bool celix_bundleContext_useServiceWithOptions(
     bool useServiceIsDone = false;
     bool called = false;
     do {
-        celixThreadMutex_lock(&data.mutex);
-        called = celix_serviceTracker_useHighestRankingService(data.svcTracker, opts->filter.serviceName, opts->callbackHandle, opts->use, opts->useWithProperties, opts->useWithOwner);
-        celixThreadMutex_unlock(&data.mutex);
+        if (celix_framework_isCurrentThreadTheEventLoop(ctx->framework)) {
+            celix_bundleContext_useServiceWithOptions_2_UseServiceTracker(&data);
+        } else {
+            long eventId = celix_framework_fireGenericEvent(ctx->framework, -1, celix_bundle_getId(ctx->bundle), "use service tracker for celix_bundleContext_useServiceWithOptions", &data, celix_bundleContext_useServiceWithOptions_2_UseServiceTracker, NULL, NULL);
+            celix_framework_waitForGenericEvent(ctx->framework, eventId);
+        }
 
         bool timeoutNotUsed = opts->waitTimeoutInSeconds == 0;
         bool timeoutExpired = celix_elapsedtime(CLOCK_MONOTONIC, startTime) > opts->waitTimeoutInSeconds;
 
+        celixThreadMutex_lock(&data.mutex);
+        called = data.called;
+        celixThreadMutex_unlock(&data.mutex);
+
         useServiceIsDone = timeoutNotUsed || timeoutExpired || called;
         if (!useServiceIsDone) {
             usleep(10);
@@ -1232,9 +1252,9 @@ bool celix_bundleContext_useServiceWithOptions(
     } while (!useServiceIsDone);
 
     if (celix_framework_isCurrentThreadTheEventLoop(ctx->framework)) {
-        celix_bundleContext_useServiceWithOptions_2_CloseServiceTracker(&data);
+        celix_bundleContext_useServiceWithOptions_3_CloseServiceTracker(&data);
     } else {
-        long eventId = celix_framework_fireGenericEvent(ctx->framework, -1, celix_bundle_getId(ctx->bundle), "close service tracker for use service", &data, celix_bundleContext_useServiceWithOptions_2_CloseServiceTracker, NULL, NULL);
+        long eventId = celix_framework_fireGenericEvent(ctx->framework, -1, celix_bundle_getId(ctx->bundle), "close service tracker for celix_bundleContext_useServiceWithOptions", &data, celix_bundleContext_useServiceWithOptions_3_CloseServiceTracker, NULL, NULL);
         celix_framework_waitForGenericEvent(ctx->framework, eventId);
     }
 
@@ -1242,6 +1262,15 @@ bool celix_bundleContext_useServiceWithOptions(
     return called;
 }
 
+static void celix_bundleContext_useServicesWithOptions_2_UseServiceTracker(void *data) {
+    celix_bundle_context_use_service_data_t* d = data;
+    assert(celix_framework_isCurrentThreadTheEventLoop(d->ctx->framework));
+
+    celixThreadMutex_lock(&d->mutex);
+    d->count = celix_serviceTracker_useServices(d->svcTracker, d->opts->filter.serviceName, d->opts->callbackHandle, d->opts->use, d->opts->useWithProperties, d->opts->useWithOwner);
+    celixThreadMutex_unlock(&d->mutex);
+}
+
 size_t celix_bundleContext_useServicesWithOptions(
         celix_bundle_context_t *ctx,
         const celix_service_use_options_t *opts) {
@@ -1251,12 +1280,13 @@ size_t celix_bundleContext_useServicesWithOptions(
 
     celix_bundle_context_use_service_data_t data = {0};
     data.ctx = ctx;
-    data.opts = opts->filter;
+    data.opts = opts;
+    celixThreadMutex_create(&data.mutex, NULL);
 
     if (celix_framework_isCurrentThreadTheEventLoop(ctx->framework)) {
         celix_bundleContext_useServiceWithOptions_1_CreateServiceTracker(&data);
     } else {
-        long eventId = celix_framework_fireGenericEvent(ctx->framework, -1, celix_bundle_getId(ctx->bundle), "create service tracker for use services", &data, celix_bundleContext_useServiceWithOptions_1_CreateServiceTracker, NULL, NULL);
+        long eventId = celix_framework_fireGenericEvent(ctx->framework, -1, celix_bundle_getId(ctx->bundle), "create service tracker for celix_bundleContext_useServicesWithOptions", &data, celix_bundleContext_useServiceWithOptions_1_CreateServiceTracker, NULL, NULL);
         celix_framework_waitForGenericEvent(ctx->framework, eventId);
     }
 
@@ -1264,17 +1294,20 @@ size_t celix_bundleContext_useServicesWithOptions(
         celix_framework_waitForEmptyEventQueue(ctx->framework); //ensure that a useService wait if a listener hooks concept, which triggers an async service registration
     }
 
-    celixThreadMutex_lock(&data.mutex);
-    size_t count = celix_serviceTracker_useServices(data.svcTracker, opts->filter.serviceName, opts->callbackHandle, opts->use, opts->useWithProperties, opts->useWithOwner);
-    celixThreadMutex_unlock(&data.mutex);
-
     if (celix_framework_isCurrentThreadTheEventLoop(ctx->framework)) {
-        celix_bundleContext_useServiceWithOptions_2_CloseServiceTracker(&data);
+        celix_bundleContext_useServicesWithOptions_2_UseServiceTracker(&data);
+        celix_bundleContext_useServiceWithOptions_3_CloseServiceTracker(&data);
     } else {
-        long eventId = celix_framework_fireGenericEvent(ctx->framework, -1, celix_bundle_getId(ctx->bundle), "close service tracker for use services", &data, celix_bundleContext_useServiceWithOptions_2_CloseServiceTracker, NULL, NULL);
+        celix_framework_fireGenericEvent(ctx->framework, -1, celix_bundle_getId(ctx->bundle), "use service tracker for celix_bundleContext_useServicesWithOptions", &data, celix_bundleContext_useServicesWithOptions_2_UseServiceTracker, NULL, NULL);
+        long eventId = celix_framework_fireGenericEvent(ctx->framework, -1, celix_bundle_getId(ctx->bundle), "close service tracker for celix_bundleContext_useServicesWithOptions", &data, celix_bundleContext_useServiceWithOptions_3_CloseServiceTracker, NULL, NULL);
         celix_framework_waitForGenericEvent(ctx->framework, eventId);
     }
 
+    celixThreadMutex_lock(&data.mutex);
+    size_t count = data.count;
+    celixThreadMutex_unlock(&data.mutex);
+    celixThreadMutex_destroy(&data.mutex);
+
     return count;
 }