in src/source/CurlApiCallbacks.c [1556:1639]
STATUS getStreamingEndpointCachingCurl(UINT64 customData, PCHAR streamName, PCHAR apiName, PServiceCallContext pServiceCallContext)
{
ENTERS();
STATUS retStatus = STATUS_SUCCESS;
PCurlApiCallbacks pCurlApiCallbacks = (PCurlApiCallbacks) customData;
PCallbacksProvider pCallbacksProvider = NULL;
UINT64 curTime, value;
STREAM_HANDLE streamHandle;
PEndpointTracker pEndpointTracker = NULL;
BOOL endpointsLocked = FALSE, emulateApiCall = TRUE;
CHK(pCurlApiCallbacks != NULL && pCurlApiCallbacks->pCallbacksProvider != NULL && pServiceCallContext != NULL, STATUS_INVALID_ARG);
pCallbacksProvider = pCurlApiCallbacks->pCallbacksProvider;
streamHandle = (STREAM_HANDLE) pServiceCallContext->customData;
// 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:
// Explicit fall-through
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;
}
}
break;
}
// Force the get endpoint call if we have no up-to-date info
if (!emulateApiCall) {
// No longer need to hold the endpoint lock
if (endpointsLocked) {
pCallbacksProvider->clientCallbacks.unlockMutexFn(pCallbacksProvider->clientCallbacks.customData, pCurlApiCallbacks->cachedEndpointsLock);
endpointsLocked = FALSE;
}
CHK_STATUS(getStreamingEndpointCurl(customData, streamName, apiName, pServiceCallContext));
// Early return
CHK(FALSE, retStatus);
}
DLOGV("Caching GetStreamingEndpoint API call");
// At this stage we should be holding the lock
CHECK(endpointsLocked);
retStatus = getStreamingEndpointResultEvent(streamHandle, SERVICE_CALL_RESULT_OK, pEndpointTracker->streamingEndpoint);
notifyCallResult(pCallbacksProvider, retStatus, streamHandle);
CleanUp:
if (endpointsLocked) {
pCallbacksProvider->clientCallbacks.unlockMutexFn(pCallbacksProvider->clientCallbacks.customData, pCurlApiCallbacks->cachedEndpointsLock);
}
LEAVES();
return retStatus;
}