diff options
Diffstat (limited to 'src/request_context.c')
-rw-r--r-- | src/request_context.c | 260 |
1 files changed, 130 insertions, 130 deletions
diff --git a/src/request_context.c b/src/request_context.c index ed4c185..bccaee8 100644 --- a/src/request_context.c +++ b/src/request_context.c @@ -33,158 +33,158 @@ S3Status S3_create_request_context(S3RequestContext **requestContextReturn) { - *requestContextReturn = - (S3RequestContext *) malloc(sizeof(S3RequestContext)); - - if (!*requestContextReturn) { - return S3StatusOutOfMemory; - } - - if (!((*requestContextReturn)->curlm = curl_multi_init())) { - free(*requestContextReturn); - return S3StatusOutOfMemory; - } - - (*requestContextReturn)->requests = 0; - - return S3StatusOK; + *requestContextReturn = + (S3RequestContext *) malloc(sizeof(S3RequestContext)); + + if (!*requestContextReturn) { + return S3StatusOutOfMemory; + } + + if (!((*requestContextReturn)->curlm = curl_multi_init())) { + free(*requestContextReturn); + return S3StatusOutOfMemory; + } + + (*requestContextReturn)->requests = 0; + + return S3StatusOK; } void S3_destroy_request_context(S3RequestContext *requestContext) { - curl_multi_cleanup(requestContext->curlm); - - // For each request in the context, call back its done method with - // 'interrupted' status - Request *r = requestContext->requests, *rFirst = r; - - if (r) do { - r->status = S3StatusInterrupted; - Request *rNext = r->next; - request_finish(r); - r = rNext; - } while (r != rFirst); - - free(requestContext); + curl_multi_cleanup(requestContext->curlm); + + // For each request in the context, call back its done method with + // 'interrupted' status + Request *r = requestContext->requests, *rFirst = r; + + if (r) do { + r->status = S3StatusInterrupted; + Request *rNext = r->next; + request_finish(r); + r = rNext; + } while (r != rFirst); + + free(requestContext); } S3Status S3_runall_request_context(S3RequestContext *requestContext) { - int requestsRemaining; - do { - fd_set readfds, writefds, exceptfds; - FD_ZERO(&readfds); - FD_ZERO(&writefds); - FD_ZERO(&exceptfds); - int maxfd; - S3Status status = S3_get_request_context_fdsets - (requestContext, &readfds, &writefds, &exceptfds, &maxfd); - if (status != S3StatusOK) { - return status; - } - // curl will return -1 if it hasn't even created any fds yet because - // none of the connections have started yet. In this case, don't - // do the select at all, because it will wait forever; instead, just - // skip it and go straight to running the underlying CURL handles - if (maxfd != -1) { - int64_t timeout = S3_get_request_context_timeout(requestContext); - struct timeval tv = { timeout / 1000, (timeout % 1000) * 1000 }; - select(maxfd + 1, &readfds, &writefds, &exceptfds, - (timeout == -1) ? 0 : &tv); - } - status = S3_runonce_request_context(requestContext, - &requestsRemaining); - if (status != S3StatusOK) { - return status; - } - } while (requestsRemaining); - - return S3StatusOK; + int requestsRemaining; + do { + fd_set readfds, writefds, exceptfds; + FD_ZERO(&readfds); + FD_ZERO(&writefds); + FD_ZERO(&exceptfds); + int maxfd; + S3Status status = S3_get_request_context_fdsets + (requestContext, &readfds, &writefds, &exceptfds, &maxfd); + if (status != S3StatusOK) { + return status; + } + // curl will return -1 if it hasn't even created any fds yet because + // none of the connections have started yet. In this case, don't + // do the select at all, because it will wait forever; instead, just + // skip it and go straight to running the underlying CURL handles + if (maxfd != -1) { + int64_t timeout = S3_get_request_context_timeout(requestContext); + struct timeval tv = { timeout / 1000, (timeout % 1000) * 1000 }; + select(maxfd + 1, &readfds, &writefds, &exceptfds, + (timeout == -1) ? 0 : &tv); + } + status = S3_runonce_request_context(requestContext, + &requestsRemaining); + if (status != S3StatusOK) { + return status; + } + } while (requestsRemaining); + + return S3StatusOK; } S3Status S3_runonce_request_context(S3RequestContext *requestContext, - int *requestsRemainingReturn) + int *requestsRemainingReturn) { - CURLMcode status; - - do { - status = curl_multi_perform(requestContext->curlm, - requestsRemainingReturn); - - switch (status) { - case CURLM_OK: - case CURLM_CALL_MULTI_PERFORM: - break; - case CURLM_OUT_OF_MEMORY: - return S3StatusOutOfMemory; - default: - return S3StatusInternalError; - } - - CURLMsg *msg; - int junk; - while ((msg = curl_multi_info_read(requestContext->curlm, &junk))) { - if (msg->msg != CURLMSG_DONE) { - return S3StatusInternalError; - } - Request *request; - if (curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, - (char **) &request) != CURLE_OK) { - return S3StatusInternalError; - } - // Remove the request from the list of requests - if (request->prev == request->next) { - // It was the only one on the list - requestContext->requests = 0; - } - else { - // It doesn't matter what the order of them are, so just in - // case request was at the head of the list, put the one after - // request to the head of the list - requestContext->requests = request->next; - request->prev->next = request->next; - request->next->prev = request->prev; - } - if ((msg->data.result != CURLE_OK) && - (request->status == S3StatusOK)) { - request->status = request_curl_code_to_status - (msg->data.result); - } - if (curl_multi_remove_handle(requestContext->curlm, - msg->easy_handle) != CURLM_OK) { - return S3StatusInternalError; - } - // Finish the request, ensuring that all callbacks have been made, - // and also releases the request - request_finish(request); - // Now, since a callback was made, there may be new requests - // queued up to be performed immediately, so do so - status = CURLM_CALL_MULTI_PERFORM; - } - } while (status == CURLM_CALL_MULTI_PERFORM); - - return S3StatusOK; + CURLMcode status; + + do { + status = curl_multi_perform(requestContext->curlm, + requestsRemainingReturn); + + switch (status) { + case CURLM_OK: + case CURLM_CALL_MULTI_PERFORM: + break; + case CURLM_OUT_OF_MEMORY: + return S3StatusOutOfMemory; + default: + return S3StatusInternalError; + } + + CURLMsg *msg; + int junk; + while ((msg = curl_multi_info_read(requestContext->curlm, &junk))) { + if (msg->msg != CURLMSG_DONE) { + return S3StatusInternalError; + } + Request *request; + if (curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, + (char **) &request) != CURLE_OK) { + return S3StatusInternalError; + } + // Remove the request from the list of requests + if (request->prev == request->next) { + // It was the only one on the list + requestContext->requests = 0; + } + else { + // It doesn't matter what the order of them are, so just in + // case request was at the head of the list, put the one after + // request to the head of the list + requestContext->requests = request->next; + request->prev->next = request->next; + request->next->prev = request->prev; + } + if ((msg->data.result != CURLE_OK) && + (request->status == S3StatusOK)) { + request->status = request_curl_code_to_status + (msg->data.result); + } + if (curl_multi_remove_handle(requestContext->curlm, + msg->easy_handle) != CURLM_OK) { + return S3StatusInternalError; + } + // Finish the request, ensuring that all callbacks have been made, + // and also releases the request + request_finish(request); + // Now, since a callback was made, there may be new requests + // queued up to be performed immediately, so do so + status = CURLM_CALL_MULTI_PERFORM; + } + } while (status == CURLM_CALL_MULTI_PERFORM); + + return S3StatusOK; } S3Status S3_get_request_context_fdsets(S3RequestContext *requestContext, - fd_set *readFdSet, fd_set *writeFdSet, - fd_set *exceptFdSet, int *maxFd) + fd_set *readFdSet, fd_set *writeFdSet, + fd_set *exceptFdSet, int *maxFd) { - return ((curl_multi_fdset(requestContext->curlm, readFdSet, writeFdSet, - exceptFdSet, maxFd) == CURLM_OK) ? - S3StatusOK : S3StatusInternalError); + return ((curl_multi_fdset(requestContext->curlm, readFdSet, writeFdSet, + exceptFdSet, maxFd) == CURLM_OK) ? + S3StatusOK : S3StatusInternalError); } int64_t S3_get_request_context_timeout(S3RequestContext *requestContext) { - long timeout; + long timeout; - if (curl_multi_timeout(requestContext->curlm, &timeout) != CURLM_OK) { - timeout = 0; - } - - return timeout; + if (curl_multi_timeout(requestContext->curlm, &timeout) != CURLM_OK) { + timeout = 0; + } + + return timeout; } |