in bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c [662:747]
static void discoveryZeroconfWatcher_refreshWatchedServices(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) {
unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime;
//mark deleted status for all watched services
CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) {
watched_service_entry_t *svcEntry = (watched_service_entry_t *)iter.value.ptrValue;
svcEntry->markDeleted = true;
}
celixThreadMutex_lock(&watcher->mutex);
CELIX_STRING_HASH_MAP_ITERATE(watcher->serviceBrowsers, iter) {
service_browser_entry_t *browserEntry = (service_browser_entry_t *)iter.value.ptrValue;
CELIX_STRING_HASH_MAP_ITERATE(browserEntry->watchedServices, iter2) {
const char *key = iter2.key;
int interfaceIndex = (int)iter2.value.longValue;
celix_autofree watched_service_entry_t *svcEntry = (watched_service_entry_t *)celix_stringHashMap_get(watcher->watchedServices, key);
if (svcEntry != NULL) {
svcEntry->markDeleted = false;
celix_steal_ptr(svcEntry);
continue;
}
char *instanceNameEnd = strrchr(key, '/');
if (instanceNameEnd == NULL || instanceNameEnd-key >= DZC_MAX_SERVICE_INSTANCE_NAME_LEN) {
celix_logHelper_error(watcher->logHelper, "Watcher: Invalid service instance key, %s.", key);
continue;
}
svcEntry = (watched_service_entry_t *)calloc(1, sizeof(*svcEntry));
if (svcEntry == NULL) {
celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc service entry.");
nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry browse after 5 seconds
continue;
}
svcEntry->resolveRef = NULL;
svcEntry->txtRecord = celix_properties_create();
if (svcEntry->txtRecord == NULL) {
celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR);
celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create txt record for service entry.");
nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry browse after 5 seconds
continue;
}
svcEntry->endpointId = NULL;
svcEntry->resolved = false;
strncpy(svcEntry->instanceName, key, instanceNameEnd-key);
svcEntry->instanceName[instanceNameEnd-key] = '\0';
svcEntry->hostname = NULL;
svcEntry->ifIndex = interfaceIndex;
svcEntry->resolvedCnt = 0;
svcEntry->reResolve = false;
svcEntry->markDeleted = false;
svcEntry->logHelper = watcher->logHelper;
int status = celix_stringHashMap_put(watcher->watchedServices, key, svcEntry);
if (status != CELIX_SUCCESS) {
celix_properties_destroy(svcEntry->txtRecord);
celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR);
celix_logHelper_error(watcher->logHelper, "Watcher: Failed to put service entry, %d.", status);
nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry browse after 5 seconds
continue;
}
celix_steal_ptr(svcEntry);
}
}
celixThreadMutex_unlock(&watcher->mutex);
//remove to be deleted services
celix_string_hash_map_iterator_t iter = celix_stringHashMap_begin(watcher->watchedServices);
while (!celix_stringHashMapIterator_isEnd(&iter)) {
watched_service_entry_t *svcEntry = (watched_service_entry_t *)iter.value.ptrValue;
if (svcEntry->markDeleted) {
celix_logHelper_trace(watcher->logHelper, "Watcher: Stop to resolve service %s on %d.", svcEntry->instanceName, svcEntry->ifIndex);
celix_stringHashMapIterator_remove(&iter);
if (svcEntry->resolveRef) {
DNSServiceRefDeallocate(svcEntry->resolveRef);
}
celix_properties_destroy(svcEntry->txtRecord);
free(svcEntry->hostname);
free(svcEntry);
} else {
celix_stringHashMapIterator_next(&iter);
}
}
discoveryZeroconfWatcher_resolveServices(watcher, &nextWorkIntervalTime);
*pNextWorkIntervalTime = nextWorkIntervalTime;
return;
}