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/06/02 16:38:49 UTC

[celix] branch master updated: fix race condition in serviceRegistry_getService.

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 4fb7d95  fix race condition in serviceRegistry_getService.
     new d5629de  Merge pull request #346 from PengZheng/fix_race_condition
4fb7d95 is described below

commit 4fb7d952cc2c386320e6524a16bd577e9e7f35f0
Author: PengZheng <ho...@gmail.com>
AuthorDate: Sun May 30 21:09:41 2021 +0800

    fix race condition in serviceRegistry_getService.
    
    Before serviceReference_setService is called for the first
    reference usage, there is a window in which the subsequent reference
    usages get NULL service. Moreover, serviceRegistration_retain
    and serviceRegistration_release are not called in pairs for invalid
    registration, which may cause assertion failure.
---
 libs/framework/src/service_registry.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/libs/framework/src/service_registry.c b/libs/framework/src/service_registry.c
index 4e2b0c4..f73e48d 100644
--- a/libs/framework/src/service_registry.c
+++ b/libs/framework/src/service_registry.c
@@ -591,15 +591,17 @@ celix_status_t serviceRegistry_getService(service_registry_pt registry, bundle_p
     if (valid) {
         serviceRegistration_retain(registration);
         serviceReference_increaseUsage(reference, &count);
-    } else {
-        *out = NULL; //invalid service registration
+        if (count == 1) {
+            serviceRegistration_getService(registration, bundle, &service);
+            serviceReference_setService(reference, service);
+        }
     }
     celixThreadRwlock_unlock(&registry->lock);
-
-    if (count == 1) {
-        serviceRegistration_getService(registration, bundle, &service);
-        serviceReference_setService(reference, service);
+    if(!valid) {
+        *out = NULL;
+        return status;
     }
+
     serviceRegistration_release(registration);
 
     /* NOTE the out argument of sr_getService should be 'const void**'
@@ -1313,4 +1315,4 @@ void celix_serviceRegistry_unregisterService(celix_service_registry_t* registry,
     } else {
         fw_log(registry->framework->logger, CELIX_LOG_LEVEL_ERROR, "Cannot unregister service for service id %li. This id is not present or owned by the provided bundle (bnd id %li)", serviceId, celix_bundle_getId(bnd));
     }
-}
\ No newline at end of file
+}