CdiReturnStatus CdiTimeoutCreate()

in src/cdi/timeout.c [196:281]


CdiReturnStatus CdiTimeoutCreate(CdiLogHandle log_handle, CdiTimeoutInstanceHandle* ret_handle_ptr)
{
    CdiReturnStatus ret = kCdiStatusOk;

    TimeoutInstanceState* state_ptr = (TimeoutInstanceState*)CdiOsMemAllocZero(sizeof(TimeoutInstanceState));
    if (state_ptr == NULL) {
        // NOTE: Must use CDI_LOG_HANDLE() to direct the log message to the desired log.
        CDI_LOG_HANDLE(log_handle, kLogError, "Insufficient memory for TimeoutInstanceState allocation");
        ret = kCdiStatusNotEnoughMemory;
    }

    state_ptr->log_handle = log_handle;

    if (ret == kCdiStatusOk) {
        if (!CdiPoolCreate("Timeout TimeoutDataState Pool", MAX_TIMERS, MAX_TIMERS_GROW, MAX_POOL_GROW_COUNT,
                            sizeof(TimeoutDataState), true, // true= Make thread-safe
                            &state_ptr->mem_pool_handle)) {
                            CDI_LOG_HANDLE(log_handle, kLogError, "ERROR: Failed to create memory pool");
                            ret = kCdiStatusNotEnoughMemory;
        }
    }

    if (ret == kCdiStatusOk) {
       if (!CdiOsCritSectionCreate(&state_ptr->critical_section)) {
            CDI_LOG_HANDLE(log_handle, kLogError, "Failed to create critical section for Timeout Instance State");
            ret = kCdiStatusNotEnoughMemory;
        }
    }

    if (ret == kCdiStatusOk) {
        if (!CdiOsSignalCreate(&state_ptr->shutdown_signal)) {
            CDI_LOG_HANDLE(log_handle, kLogError, "Failed to create signal for Timeout Shutdown");
            ret = kCdiStatusNotEnoughMemory;
        }
    }

    if (ret == kCdiStatusOk) {
        if (!CdiOsSignalCreate(&state_ptr->stop_signal)) {
            CDI_LOG_HANDLE(log_handle, kLogError, "Failed to create signal for Timeout Timer Stop");
            ret = kCdiStatusNotEnoughMemory;
        }
    }

    if (ret == kCdiStatusOk) {
        if (!CdiOsSignalCreate(&state_ptr->go_signal)) {
            CDI_LOG_HANDLE(log_handle, kLogError, "Failed to create signal for Timeout Go");
            ret = kCdiStatusNotEnoughMemory;
        }
    }

    if (ret == kCdiStatusOk) {
        if (!CdiOsThreadCreate(TimeoutMainThread, &state_ptr->main_thread_id, "TimeoutMain", (void*)state_ptr, NULL)) {
            CDI_LOG_HANDLE(log_handle, kLogError, "Timeout main thread creation failed");
            ret = kCdiStatusFatal;
        }
    }

    if (ret == kCdiStatusOk) {
        if (!CdiFifoCreate("Timeout CB FIFO", MAX_TIMERS, sizeof(TimeoutCbFifoData), NULL, NULL,
                           &state_ptr->cb_fifo_handle)) {
            CDI_LOG_HANDLE(log_handle, kLogError, "Callback FIFO creation failed");
            ret = kCdiStatusNotEnoughMemory;
        }
    }

    if (ret == kCdiStatusOk) {
        if (!CdiOsThreadCreate(TimeoutCbThread, &state_ptr->cb_thread_id, "TimeoutCb", (void*)state_ptr, NULL)) {
            CDI_LOG_HANDLE(log_handle, kLogError, "Timeout callback thread creation failed");
            ret = kCdiStatusFatal;
        }
    }

    if (ret == kCdiStatusOk) {
        CdiListInit(&state_ptr->timeout_list);
    }

    // If the timeout creation process fails a NULL handle is returned and the partially created timeout is destroyed,
    if (ret == kCdiStatusOk) {
        *ret_handle_ptr = (CdiTimeoutInstanceHandle)state_ptr;
    } else {
        *ret_handle_ptr = NULL;
        CdiTimeoutDestroy(state_ptr);
    }

    return ret;
}