Skip to content
Permalink
Browse files
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.
  • Loading branch information
PengZheng committed May 30, 2021
1 parent 0cd23ad commit 4fb7d952cc2c386320e6524a16bd577e9e7f35f0
Showing 1 changed file with 9 additions and 7 deletions.
@@ -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));
}
}
}

0 comments on commit 4fb7d95

Please sign in to comment.