in src/source/CurlApiCallbacks.c [528:596]
STATUS curlApiCallbacksShutdownActiveUploads(PCurlApiCallbacks pCurlApiCallbacks, STREAM_HANDLE streamHandle, UPLOAD_HANDLE uploadHandle,
UINT64 timeout, BOOL fromCurlThread, BOOL killThread)
{
ENTERS();
STATUS retStatus = STATUS_SUCCESS;
PCallbacksProvider pCallbacksProvider = NULL;
BOOL uploadsLocked = FALSE;
PDoubleListNode pCurNode, pNode;
PCurlRequest pCurlRequest;
CHK(pCurlApiCallbacks != NULL && pCurlApiCallbacks->pCallbacksProvider != NULL, STATUS_INVALID_ARG);
pCallbacksProvider = pCurlApiCallbacks->pCallbacksProvider;
// Lock for the guards for exclusive access
pCallbacksProvider->clientCallbacks.lockMutexFn(pCallbacksProvider->clientCallbacks.customData, pCurlApiCallbacks->activeUploadsLock);
uploadsLocked = TRUE;
// Iterate through the list and find the requests matching the stream
CHK_STATUS(doubleListGetHeadNode(pCurlApiCallbacks->pActiveUploads, &pNode));
while (pNode != NULL) {
pCurlRequest = (PCurlRequest) pNode->data;
// Get the next node before processing
pCurNode = pNode;
CHK_STATUS(doubleListGetNextNode(pNode, &pNode));
// Process the curl request ONLY if the stream handle matches or the specified handle is invalid,
// it's not already in terminating state
// and if the uploadHandle is invalid or is equal to the current
if ((!IS_VALID_STREAM_HANDLE(streamHandle) || pCurlRequest->streamHandle == streamHandle) &&
(!IS_VALID_UPLOAD_HANDLE(uploadHandle) || uploadHandle == pCurlRequest->uploadHandle)) {
if (killThread && ATOMIC_LOAD_BOOL(&pCurlRequest->requestInfo.terminating)) {
if (ATOMIC_LOAD_BOOL(&pCurlRequest->blockedInCurl)) {
THREAD_CANCEL(pCurlRequest->threadId);
}
} else if (!fromCurlThread) {
// Set the terminating status on the request
ATOMIC_STORE_BOOL(&pCurlRequest->requestInfo.terminating, TRUE);
if (ATOMIC_LOAD_BOOL(&pCurlRequest->blockedInCurl)) {
// Terminate the curl request in flight
terminateCurlSession(pCurlRequest->pCurlResponse, timeout);
}
}
if (fromCurlThread || (killThread && ATOMIC_LOAD_BOOL(&pCurlRequest->requestInfo.terminating))) {
// if curlApiCallbacksShutdownActiveUploads is being called by curl thread, then free all resources
// and the curl thread will then exit. Otherwise also free when we explicitly kill the thread.
CHK_STATUS(doubleListDeleteNode(pCurlApiCallbacks->pActiveUploads, pCurNode));
// Free the request object
CHK_STATUS(freeCurlRequest(&pCurlRequest));
}
}
}
CleanUp:
CHK_LOG_ERR(retStatus);
// Unlock only if previously locked
if (uploadsLocked) {
pCallbacksProvider->clientCallbacks.unlockMutexFn(pCallbacksProvider->clientCallbacks.customData, pCurlApiCallbacks->activeUploadsLock);
}
LEAVES();
return retStatus;
}