CdiReturnStatus EndpointManagerCreate()

in src/cdi/endpoint_manager.c [469:567]


CdiReturnStatus EndpointManagerCreate(CdiConnectionHandle handle, CdiCoreStatsCallback stats_cb_ptr,
                                      CdiUserCbParameter stats_user_cb_param,
                                      const CdiStatsConfigData* stats_config_ptr, EndpointManagerHandle* ret_handle_ptr)
{
    CdiReturnStatus rs = kCdiStatusOk;
    EndpointManagerState* mgr_ptr = (EndpointManagerState*)CdiOsMemAllocZero(sizeof *mgr_ptr);
    if (mgr_ptr == NULL) {
        return kCdiStatusNotEnoughMemory;
    }

    mgr_ptr->connection_state_ptr = handle;

    if (!CdiOsSignalCreate(&mgr_ptr->shutdown_signal)) {
        rs = kCdiStatusNotEnoughMemory;
    }

    if (kCdiStatusOk == rs) {
        if (!CdiOsSignalCreate(&mgr_ptr->new_command_signal)) {
            rs = kCdiStatusNotEnoughMemory;
        }
    }

    if (kCdiStatusOk == rs) {
        if (!CdiOsSignalCreate(&mgr_ptr->all_threads_running_signal)) {
            rs = kCdiStatusNotEnoughMemory;
        } else {
            // Set by default so on startup, threads are not blocked in EndpointManagerThreadWait().
            CdiOsSignalSet(mgr_ptr->all_threads_running_signal);
        }
    }
    if (kCdiStatusOk == rs) {
        if (!CdiOsSignalCreate(&mgr_ptr->poll_thread_exit_signal)) {
            rs = kCdiStatusNotEnoughMemory;
        }
    }
    if (kCdiStatusOk == rs) {
        if (!CdiOsSignalCreate(&mgr_ptr->all_threads_waiting_signal)) {
            rs = kCdiStatusNotEnoughMemory;
        }
    }
    if (kCdiStatusOk == rs) {
        if (!CdiOsSignalCreate(&mgr_ptr->command_done_signal)) {
            rs = kCdiStatusNotEnoughMemory;
        }
    }
    if (kCdiStatusOk == rs) {
        if (!CdiOsSignalCreate(&mgr_ptr->endpoints_destroyed_signal)) {
            rs = kCdiStatusNotEnoughMemory;
        }
    }
    if (kCdiStatusOk == rs) {
        if (!CdiOsCritSectionCreate(&mgr_ptr->endpoint_list_lock)) {
            rs = kCdiStatusNotEnoughMemory;
        }
    }
    if (kCdiStatusOk == rs) {
        if (!CdiOsCritSectionCreate(&mgr_ptr->state_lock)) {
            rs = kCdiStatusNotEnoughMemory;
        }
    }
    if (kCdiStatusOk == rs) {
        if (!CdiQueueCreate("DestroyEndpoint Queue", CDI_MAX_ENDPOINTS_PER_CONNECTION, NO_GROW_SIZE, NO_GROW_COUNT,
                            sizeof(CdiEndpointHandle), kQueueSignalNone,
                            &mgr_ptr->destroy_endpoint_queue_handle)) {
            rs = kCdiStatusAllocationFailed;
        }
    }

    if (kCdiStatusOk == rs) {
        // Create statistics state resources.
        rs = StatsCreate(handle, stats_cb_ptr, stats_user_cb_param, cdi_global_context.cw_sdk_handle,
                         cdi_global_context.metrics_gathering_sdk_handle, &handle->stats_state_ptr);
    }
    if (kCdiStatusOk == rs) {
        // Set the initial stats configuration settings. Since they have not been set yet, use true here to ensure
        // they are applied.
        rs = CoreStatsConfigureInternal(handle, stats_config_ptr, true);
    }

    if (kCdiStatusOk == rs) {
        CdiListInit(&mgr_ptr->endpoint_list);

        // Start the thread which will service endpoint state changes.
        if (!CdiOsThreadCreate(EndpointManagerThread, &mgr_ptr->thread_id, "EPManager", mgr_ptr,
                               handle->start_signal)) {
            rs = kCdiStatusAllocationFailed;
        }
    }

    if (kCdiStatusOk != rs) {
        EndpointManagerDestroy(mgr_ptr);
        CdiOsMemFree(mgr_ptr);
        mgr_ptr = NULL;
    }

    *ret_handle_ptr = (EndpointManagerHandle)mgr_ptr;

    return rs;
}