diff options
Diffstat (limited to 'Utilities/cmcurl/lib/easy.c')
-rw-r--r-- | Utilities/cmcurl/lib/easy.c | 78 |
1 files changed, 38 insertions, 40 deletions
diff --git a/Utilities/cmcurl/lib/easy.c b/Utilities/cmcurl/lib/easy.c index dc48706..a04dbed 100644 --- a/Utilities/cmcurl/lib/easy.c +++ b/Utilities/cmcurl/lib/easy.c @@ -58,7 +58,6 @@ #include "multiif.h" #include "select.h" #include "cfilters.h" -#include "cw-out.h" #include "sendf.h" /* for failf function prototype */ #include "connect.h" /* for Curl_getconnectinfo */ #include "slist.h" @@ -729,6 +728,8 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events) /* clear this as early as possible */ data->set.errorbuffer[0] = 0; + data->state.os_errno = 0; + if(data->multi) { failf(data, "easy handle already used in multi handle"); return CURLE_FAILED_INIT; @@ -1086,6 +1087,7 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) int oldstate; int newstate; bool recursive = FALSE; + bool keep_changed, unpause_read, not_all_paused; if(!GOOD_EASY_HANDLE(data) || !data->conn) /* crazy input, don't continue */ @@ -1101,51 +1103,47 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) | ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0); - if((newstate & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) == oldstate) { - /* Not changing any pause state, return */ - DEBUGF(infof(data, "pause: no change, early return")); - return CURLE_OK; - } - - /* Unpause parts in active mime tree. */ - if((k->keepon & ~newstate & KEEP_SEND_PAUSE) && - (data->mstate == MSTATE_PERFORMING || - data->mstate == MSTATE_RATELIMITING)) { - result = Curl_creader_unpause(data); - if(result) - return result; - } - - /* put it back in the keepon */ + keep_changed = ((newstate & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) != oldstate); + not_all_paused = (newstate & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) != + (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE); + unpause_read = ((k->keepon & ~newstate & KEEP_SEND_PAUSE) && + (data->mstate == MSTATE_PERFORMING || + data->mstate == MSTATE_RATELIMITING)); + /* Unpausing writes is detected on the next run in + * transfer.c:Curl_readwrite(). This is because this may result + * in a transfer error if the application's callbacks fail */ + + /* Set the new keepon state, so it takes effect no matter what error + * may happen afterwards. */ k->keepon = newstate; - if(!(newstate & KEEP_RECV_PAUSE)) { - Curl_conn_ev_data_pause(data, FALSE); - result = Curl_cw_out_flush(data); - if(result) - return result; - } - - /* if there's no error and we're not pausing both directions, we want - to have this handle checked soon */ - if((newstate & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) != - (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) { - Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */ - + /* If not completely pausing both directions now, run again in any case. */ + if(not_all_paused) { + Curl_expire(data, 0, EXPIRE_RUN_NOW); /* reset the too-slow time keeper */ data->state.keeps_speed.tv_sec = 0; - - if(!Curl_cw_out_is_paused(data)) - /* if not pausing again, force a recv/send check of this connection as - the data might've been read off the socket already */ - data->state.select_bits = CURL_CSELECT_IN | CURL_CSELECT_OUT; - if(data->multi) { - if(Curl_update_timer(data->multi)) - return CURLE_ABORTED_BY_CALLBACK; + /* Simulate socket events on next run for unpaused directions */ + if(!(newstate & KEEP_SEND_PAUSE)) + data->state.select_bits |= CURL_CSELECT_OUT; + if(!(newstate & KEEP_RECV_PAUSE)) + data->state.select_bits |= CURL_CSELECT_IN; + /* On changes, tell application to update its timers. */ + if(keep_changed && data->multi) { + if(Curl_update_timer(data->multi)) { + result = CURLE_ABORTED_BY_CALLBACK; + goto out; + } } } - if(!data->state.done) + if(unpause_read) { + result = Curl_creader_unpause(data); + if(result) + goto out; + } + +out: + if(!result && !data->state.done && keep_changed) /* This transfer may have been moved in or out of the bundle, update the corresponding socket callback, if used */ result = Curl_updatesocket(data); @@ -1305,7 +1303,7 @@ static int conn_upkeep(struct Curl_easy *data, conn->handler->connection_check(data, conn, CONNCHECK_KEEPALIVE); } else { - /* Do the generic action on the FIRSTSOCKE filter chain */ + /* Do the generic action on the FIRSTSOCKET filter chain */ Curl_conn_keep_alive(data, conn, FIRSTSOCKET); } Curl_detach_connection(data); |