mirror of
https://github.com/curl/curl.git
synced 2026-04-15 01:21:44 +03:00
multi: add xfer_buf to multi handle
- can be borrowed by transfer during recv-write operation - needs to be released before borrowing again - adjustis size to `data->set.buffer_size` - used in transfer.c readwrite_data() Closes #12805
This commit is contained in:
parent
c54d0ff6b3
commit
476adfeac0
10 changed files with 113 additions and 25 deletions
78
lib/multi.c
78
lib/multi.c
|
|
@ -94,6 +94,7 @@ static CURLMcode add_next_timeout(struct curltime now,
|
|||
static CURLMcode multi_timeout(struct Curl_multi *multi,
|
||||
long *timeout_ms);
|
||||
static void process_pending_handles(struct Curl_multi *multi);
|
||||
static void multi_xfer_buf_free(struct Curl_multi *multi);
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
static const char * const multi_statename[]={
|
||||
|
|
@ -189,6 +190,10 @@ static void mstate(struct Curl_easy *data, CURLMstate state
|
|||
/* changing to COMPLETED means there's one less easy handle 'alive' */
|
||||
DEBUGASSERT(data->multi->num_alive > 0);
|
||||
data->multi->num_alive--;
|
||||
if(!data->multi->num_alive) {
|
||||
/* free the transfer buffer when we have no more active transfers */
|
||||
multi_xfer_buf_free(data->multi);
|
||||
}
|
||||
}
|
||||
|
||||
/* if this state has an init-function, run it */
|
||||
|
|
@ -784,7 +789,6 @@ static CURLcode multi_done(struct Curl_easy *data,
|
|||
data->state.lastconnect_id = -1;
|
||||
}
|
||||
|
||||
Curl_safefree(data->state.buffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -1891,12 +1895,9 @@ static CURLcode readrewind(struct Curl_easy *data)
|
|||
*/
|
||||
CURLcode Curl_preconnect(struct Curl_easy *data)
|
||||
{
|
||||
if(!data->state.buffer) {
|
||||
data->state.buffer = malloc(data->set.buffer_size + 1);
|
||||
if(!data->state.buffer)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* this used to do data->state.buffer allocation,
|
||||
maybe remove completely now? */
|
||||
(void)data;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
|
@ -2450,7 +2451,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||
{
|
||||
char *newurl = NULL;
|
||||
bool retry = FALSE;
|
||||
DEBUGASSERT(data->state.buffer);
|
||||
/* check if over send speed */
|
||||
send_timeout_ms = 0;
|
||||
if(data->set.max_send_speed)
|
||||
|
|
@ -2883,6 +2883,7 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
|
|||
Curl_free_multi_ssl_backend_data(multi->ssl_backend_data);
|
||||
#endif
|
||||
|
||||
multi_xfer_buf_free(multi);
|
||||
free(multi);
|
||||
|
||||
return CURLM_OK;
|
||||
|
|
@ -3819,3 +3820,64 @@ struct Curl_easy **curl_multi_get_handles(struct Curl_multi *multi)
|
|||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
CURLcode Curl_multi_xfer_buf_borrow(struct Curl_easy *data,
|
||||
char **pbuf, size_t *pbuflen)
|
||||
{
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->multi);
|
||||
*pbuf = NULL;
|
||||
*pbuflen = 0;
|
||||
if(!data->multi) {
|
||||
failf(data, "transfer has no multi handle");
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
if(!data->set.buffer_size) {
|
||||
failf(data, "transfer buffer size is 0");
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
if(data->multi->xfer_buf_borrowed) {
|
||||
failf(data, "attempt to borrow xfer_buf when already borrowed");
|
||||
return CURLE_AGAIN;
|
||||
}
|
||||
|
||||
if(data->multi->xfer_buf &&
|
||||
data->set.buffer_size > data->multi->xfer_buf_len) {
|
||||
/* not large enough, get a new one */
|
||||
free(data->multi->xfer_buf);
|
||||
data->multi->xfer_buf = NULL;
|
||||
data->multi->xfer_buf_len = 0;
|
||||
}
|
||||
|
||||
if(!data->multi->xfer_buf) {
|
||||
data->multi->xfer_buf = malloc((size_t)data->set.buffer_size);
|
||||
if(!data->multi->xfer_buf) {
|
||||
failf(data, "could not allocate xfer_buf of %zu bytes",
|
||||
(size_t)data->set.buffer_size);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
data->multi->xfer_buf_len = data->set.buffer_size;
|
||||
}
|
||||
|
||||
data->multi->xfer_buf_borrowed = TRUE;
|
||||
*pbuf = data->multi->xfer_buf;
|
||||
*pbuflen = data->multi->xfer_buf_len;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_multi_xfer_buf_release(struct Curl_easy *data, char *buf)
|
||||
{
|
||||
(void)buf;
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->multi);
|
||||
DEBUGASSERT(!buf || data->multi->xfer_buf == buf);
|
||||
data->multi->xfer_buf_borrowed = FALSE;
|
||||
}
|
||||
|
||||
static void multi_xfer_buf_free(struct Curl_multi *multi)
|
||||
{
|
||||
DEBUGASSERT(multi);
|
||||
Curl_safefree(multi->xfer_buf);
|
||||
multi->xfer_buf_len = 0;
|
||||
multi->xfer_buf_borrowed = FALSE;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue