STATUS checkApiCallEmulation()

in src/source/CurlApiCallbacks.c [2222:2287]


STATUS checkApiCallEmulation(PCurlApiCallbacks pCurlApiCallbacks, STREAM_HANDLE streamHandle, PBOOL pEmulateApiCall)
{
    ENTERS();
    STATUS retStatus = STATUS_SUCCESS;
    BOOL endpointsLocked = FALSE, emulateApiCall = TRUE;
    PCallbacksProvider pCallbacksProvider = NULL;
    UINT64 curTime, value;
    PEndpointTracker pEndpointTracker = NULL;

    CHK(pCurlApiCallbacks != NULL && pCurlApiCallbacks->pCallbacksProvider != NULL && pEmulateApiCall != NULL, STATUS_NULL_ARG);
    pCallbacksProvider = pCurlApiCallbacks->pCallbacksProvider;

    // We check whether we have already made the call by checking
    // for the presence of the endpoint in the cache.
    switch (pCurlApiCallbacks->cacheType) {
        case API_CALL_CACHE_TYPE_NONE:
            emulateApiCall = FALSE;
            break;

        case API_CALL_CACHE_TYPE_ENDPOINT_ONLY:
            emulateApiCall = TRUE;
            break;

        case API_CALL_CACHE_TYPE_ALL:
            pCallbacksProvider->clientCallbacks.lockMutexFn(pCallbacksProvider->clientCallbacks.customData, pCurlApiCallbacks->cachedEndpointsLock);
            endpointsLocked = TRUE;

            // Attempt to retrieve the cached value
            retStatus = hashTableGet(pCurlApiCallbacks->pCachedEndpoints, (UINT64) streamHandle, &value);

            CHK(retStatus == STATUS_HASH_KEY_NOT_PRESENT || retStatus == STATUS_SUCCESS, retStatus);

            if (retStatus == STATUS_HASH_KEY_NOT_PRESENT) {
                emulateApiCall = FALSE;

                // Reset the status if not found
                retStatus = STATUS_SUCCESS;
            } else {
                pEndpointTracker = (PEndpointTracker) value;
                curTime = pCallbacksProvider->clientCallbacks.getCurrentTimeFn(pCallbacksProvider->clientCallbacks.customData);

                if (pEndpointTracker == NULL || pEndpointTracker->streamingEndpoint[0] == '\0' ||
                    pEndpointTracker->endpointLastUpdateTime + pCurlApiCallbacks->cacheUpdatePeriod <= curTime) {
                    emulateApiCall = FALSE;
                }
            }

            // No longer need to hold the endpoint lock
            pCallbacksProvider->clientCallbacks.unlockMutexFn(pCallbacksProvider->clientCallbacks.customData, pCurlApiCallbacks->cachedEndpointsLock);
            endpointsLocked = FALSE;
            break;
    }

CleanUp:

    if (pEmulateApiCall != NULL) {
        *pEmulateApiCall = emulateApiCall;
    }

    if (endpointsLocked) {
        pCallbacksProvider->clientCallbacks.unlockMutexFn(pCallbacksProvider->clientCallbacks.customData, pCurlApiCallbacks->cachedEndpointsLock);
    }

    LEAVES();
    return retStatus;
}