celix_status_t discoveryZeroconfWatcher_create()

in bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c [124:206]


celix_status_t discoveryZeroconfWatcher_create(celix_bundle_context_t *ctx, celix_log_helper_t *logHelper, discovery_zeroconf_watcher_t **watcherOut) {
    celix_status_t status = CELIX_SUCCESS;
    celix_autofree discovery_zeroconf_watcher_t *watcher = (discovery_zeroconf_watcher_t *)calloc(1, sizeof(*watcher));
    if (watcher == NULL) {
        celix_logHelper_error(logHelper, "Watcher: Failed to alloc watcher.");
        return CELIX_ENOMEM;
    }
    watcher->logHelper = logHelper;
    watcher->ctx = ctx;
    watcher->sharedRef = NULL;
    watcher->eventFd = eventfd(0, 0);
    if (watcher->eventFd < 0) {
        celix_logHelper_error(logHelper, "Watcher: Failed to open event fd, %d.", errno);
        return CELIX_ERROR_MAKE(CELIX_FACILITY_CERRNO, errno);
    }
    celix_auto(celix_fd_t) eventFd = watcher->eventFd;

    const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, NULL);
    if (fwUuid == NULL || strlen(fwUuid) >= sizeof(watcher->fwUuid)) {
        celix_logHelper_error(logHelper, "Watcher: Failed to get framework uuid.");
        return CELIX_BUNDLE_EXCEPTION;
    }
    strcpy(watcher->fwUuid, fwUuid);

    status = celixThreadMutex_create(&watcher->mutex, NULL);
    if (status != CELIX_SUCCESS) {
        celix_logHelper_error(logHelper, "Watcher: Failed to create mutex, %d.", status);
        return status;
    }
    celix_autoptr(celix_thread_mutex_t) mutex = &watcher->mutex;
    celix_autoptr(celix_string_hash_map_t) serviceBrowsers = watcher->serviceBrowsers = celix_stringHashMap_create();
    if (serviceBrowsers == NULL) {
        celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR);
        celix_logHelper_error(logHelper, "Watcher: Failed to create service browsers map.");
        return CELIX_ENOMEM;
    }
    celix_string_hash_map_create_options_t epOpts = CELIX_EMPTY_STRING_HASH_MAP_CREATE_OPTIONS;
    epOpts.storeKeysWeakly = true;
    celix_autoptr(celix_string_hash_map_t) watchedEndpoints =
        watcher->watchedEndpoints = celix_stringHashMap_createWithOptions(&epOpts);
    if (watchedEndpoints == NULL) {
        celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR);
        celix_logHelper_error(logHelper, "Watcher: Failed to create endpoints map.");
        return CELIX_ENOMEM;
    }
    celix_autoptr(celix_string_hash_map_t) watchedHosts = watcher->watchedHosts = celix_stringHashMap_create();
    if (watchedHosts == NULL) {
        celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR);
        celix_logHelper_error(logHelper, "Watcher: Failed to create hosts map.");
        return CELIX_ENOMEM;
    }
    celix_autoptr(celix_string_hash_map_t) watchedServices =
        watcher->watchedServices = celix_stringHashMap_create();
    if (watchedServices == NULL) {
        celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR);
        celix_logHelper_error(logHelper, "Watcher: Failed to create services map.");
        return CELIX_ENOMEM;
    }
    celix_autoptr(celix_long_hash_map_t) epls =
        watcher->epls = celix_longHashMap_create();
    if (epls == NULL) {
        celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR);
        celix_logHelper_error(logHelper, "Watcher: Failed to create endpoint listener map.");
        return CELIX_ENOMEM;
    }

    watcher->running = true;
    status = celixThread_create(&watcher->watchEPThread,NULL, discoveryZeroconfWatcher_watchEPThread, watcher);
    if (status != CELIX_SUCCESS) {
        return status;
    }
    celixThread_setName(&watcher->watchEPThread, "DiscWatcher");

    celix_steal_ptr(epls);
    celix_steal_ptr(watchedServices);
    celix_steal_ptr(watchedHosts);
    celix_steal_ptr(watchedEndpoints);
    celix_steal_ptr(serviceBrowsers);
    celix_steal_ptr(mutex);
    celix_steal_fd(&eventFd);
    *watcherOut = celix_steal_ptr(watcher);
    return CELIX_SUCCESS;
}