diff options
Diffstat (limited to 'Utilities/cmcurl/lib/pipeline.c')
-rw-r--r-- | Utilities/cmcurl/lib/pipeline.c | 119 |
1 files changed, 106 insertions, 13 deletions
diff --git a/Utilities/cmcurl/lib/pipeline.c b/Utilities/cmcurl/lib/pipeline.c index 8d2544b..1b38836 100644 --- a/Utilities/cmcurl/lib/pipeline.c +++ b/Utilities/cmcurl/lib/pipeline.c @@ -6,7 +6,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se> - * Copyright (C) 2013-2014, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2013-2015, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -32,7 +32,6 @@ #include "pipeline.h" #include "sendf.h" #include "rawstr.h" -#include "bundles.h" #include "curl_memory.h" /* The last #include file should be: */ @@ -49,15 +48,13 @@ static void site_blacklist_llist_dtor(void *user, void *element) (void)user; Curl_safefree(entry->hostname); - Curl_safefree(entry); + free(entry); } static void server_blacklist_llist_dtor(void *user, void *element) { - char *server_name = element; (void)user; - - Curl_safefree(server_name); + free(element); } bool Curl_pipeline_penalized(struct SessionHandle *data, @@ -94,20 +91,29 @@ bool Curl_pipeline_penalized(struct SessionHandle *data, return FALSE; } +static CURLcode addHandleToPipeline(struct SessionHandle *data, + struct curl_llist *pipeline) +{ + if(!Curl_llist_insert_next(pipeline, pipeline->tail, data)) + return CURLE_OUT_OF_MEMORY; + return CURLE_OK; +} + + CURLcode Curl_add_handle_to_pipeline(struct SessionHandle *handle, struct connectdata *conn) { struct curl_llist_element *sendhead = conn->send_pipe->head; struct curl_llist *pipeline; - CURLcode rc; + CURLcode result; pipeline = conn->send_pipe; - rc = Curl_addHandleToPipeline(handle, pipeline); + result = addHandleToPipeline(handle, pipeline); if(pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) { /* this is a new one as head, expire it */ - conn->writechannel_inuse = FALSE; /* not in use yet */ + Curl_pipeline_leave_write(conn); /* not in use yet */ Curl_expire(conn->send_pipe->head->ptr, 1); } @@ -115,7 +121,7 @@ CURLcode Curl_add_handle_to_pipeline(struct SessionHandle *handle, print_pipeline(conn); #endif - return rc; + return result; } /* Move this transfer from the sending list to the receiving list. @@ -138,7 +144,7 @@ void Curl_move_handle_from_send_to_recv_pipe(struct SessionHandle *handle, if(conn->send_pipe->head) { /* Since there's a new easy handle at the start of the send pipeline, set its timeout value to 1ms to make it trigger instantly */ - conn->writechannel_inuse = FALSE; /* not used now */ + Curl_pipeline_leave_write(conn); /* not used now */ #ifdef DEBUGBUILD infof(conn->data, "%p is at send pipe head B!\n", (void *)conn->send_pipe->head->ptr); @@ -251,7 +257,7 @@ CURLMcode Curl_pipeline_set_site_blacklist(char **sites, bool Curl_pipeline_server_blacklisted(struct SessionHandle *handle, char *server_name) { - if(handle->multi) { + if(handle->multi && server_name) { struct curl_llist *blacklist = Curl_multi_pipelining_server_bl(handle->multi); @@ -272,7 +278,7 @@ bool Curl_pipeline_server_blacklisted(struct SessionHandle *handle, } } - infof(handle, "Server %s is not blacklisted\n", server_name); + DEBUGF(infof(handle, "Server %s is not blacklisted\n", server_name)); } return FALSE; } @@ -314,6 +320,93 @@ CURLMcode Curl_pipeline_set_server_blacklist(char **servers, return CURLM_OK; } +static bool pipe_head(struct SessionHandle *data, + struct curl_llist *pipeline) +{ + struct curl_llist_element *curr = pipeline->head; + if(curr) + return (curr->ptr == data) ? TRUE : FALSE; + + return FALSE; +} + +/* returns TRUE if the given handle is head of the recv pipe */ +bool Curl_recvpipe_head(struct SessionHandle *data, + struct connectdata *conn) +{ + return pipe_head(data, conn->recv_pipe); +} + +/* returns TRUE if the given handle is head of the send pipe */ +bool Curl_sendpipe_head(struct SessionHandle *data, + struct connectdata *conn) +{ + return pipe_head(data, conn->send_pipe); +} + + +/* + * Check if the write channel is available and this handle as at the head, + * then grab the channel and return TRUE. + * + * If not available, return FALSE. + */ + +bool Curl_pipeline_checkget_write(struct SessionHandle *data, + struct connectdata *conn) +{ + if(conn->bits.multiplex) + /* when multiplexing, we can use it at once */ + return TRUE; + + if(!conn->writechannel_inuse && Curl_sendpipe_head(data, conn)) { + /* Grab the channel */ + conn->writechannel_inuse = TRUE; + return TRUE; + } + return FALSE; +} + + +/* + * Check if the read channel is available and this handle as at the head, then + * grab the channel and return TRUE. + * + * If not available, return FALSE. + */ + +bool Curl_pipeline_checkget_read(struct SessionHandle *data, + struct connectdata *conn) +{ + if(conn->bits.multiplex) + /* when multiplexing, we can use it at once */ + return TRUE; + + if(!conn->readchannel_inuse && Curl_recvpipe_head(data, conn)) { + /* Grab the channel */ + conn->readchannel_inuse = TRUE; + return TRUE; + } + return FALSE; +} + +/* + * The current user of the pipeline write channel gives it up. + */ +void Curl_pipeline_leave_write(struct connectdata *conn) +{ + conn->writechannel_inuse = FALSE; +} + +/* + * The current user of the pipeline read channel gives it up. + */ +void Curl_pipeline_leave_read(struct connectdata *conn) +{ + conn->readchannel_inuse = FALSE; +} + + #if 0 void print_pipeline(struct connectdata *conn) { |