static void discoveryZeroconfWatcher_refreshWatchedServices()

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;
}