STATUS curlApiCallbacksShutdownActiveUploads()

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;
}