mirror of
https://github.com/curl/curl.git
synced 2026-08-24 19:03:40 +03:00
multi: add notifications API
Add infrastructure to colled and dispatch notifications for transfers and the multi handle in general. Applications can register a callback and en-/disable notification type the are interested in. Without a callback installed, notifications are not collected. Same when a notification type has not been enabled. Memory allocation failures on adding notifications lead to a general multi failure state and result in CURLM_OUT_OF_MEMORY returned from curl_multi_perform() and curl_multi_socket*() invocations. Closes #18432
This commit is contained in:
parent
f4e83a0adc
commit
357808f4ad
24 changed files with 767 additions and 44 deletions
|
|
@ -1464,26 +1464,8 @@ struct contextuv {
|
|||
struct datauv *uv;
|
||||
};
|
||||
|
||||
static CURLcode check_finished(struct parastate *s);
|
||||
|
||||
static void check_multi_info(struct datauv *uv)
|
||||
{
|
||||
CURLcode result;
|
||||
|
||||
result = check_finished(uv->s);
|
||||
if(result && !uv->s->result)
|
||||
uv->s->result = result;
|
||||
|
||||
if(uv->s->more_transfers) {
|
||||
result = add_parallel_transfers(uv->s->multi, uv->s->share,
|
||||
&uv->s->more_transfers,
|
||||
&uv->s->added_transfers);
|
||||
if(result && !uv->s->result)
|
||||
uv->s->result = result;
|
||||
if(result)
|
||||
uv_stop(uv->loop);
|
||||
}
|
||||
}
|
||||
static void mnotify(CURLM *multi, unsigned int notification,
|
||||
CURL *easy, void *user_data);
|
||||
|
||||
/* callback from libuv on socket activity */
|
||||
static void on_uv_socket(uv_poll_t *req, int status, int events)
|
||||
|
|
@ -1510,7 +1492,6 @@ static void on_uv_timeout(uv_timer_t *req)
|
|||
if(uv && uv->s) {
|
||||
curl_multi_socket_action(uv->s->multi, CURL_SOCKET_TIMEOUT, 0,
|
||||
&uv->s->still_running);
|
||||
check_multi_info(uv);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1596,8 +1577,6 @@ static int cb_socket(CURL *easy, curl_socket_t s, int action,
|
|||
uv_poll_stop(&c->poll_handle);
|
||||
destroy_context(c);
|
||||
curl_multi_assign(uv->s->multi, s, NULL);
|
||||
/* check if we can do more now */
|
||||
check_multi_info(uv);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1641,10 +1620,6 @@ static CURLcode parallel_event(struct parastate *s)
|
|||
curl_mfprintf(tool_stderr, "parallel_event: uv_run() returned\n");
|
||||
#endif
|
||||
|
||||
result = check_finished(s);
|
||||
if(result && !s->result)
|
||||
s->result = result;
|
||||
|
||||
/* early exit called */
|
||||
if(s->wrapitup) {
|
||||
if(s->still_running && !s->wrapitup_processed) {
|
||||
|
|
@ -1657,13 +1632,6 @@ static CURLcode parallel_event(struct parastate *s)
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(s->more_transfers) {
|
||||
result = add_parallel_transfers(s->multi, s->share, &s->more_transfers,
|
||||
&s->added_transfers);
|
||||
if(result && !s->result)
|
||||
s->result = result;
|
||||
}
|
||||
}
|
||||
|
||||
result = s->result;
|
||||
|
|
@ -1758,6 +1726,27 @@ static CURLcode check_finished(struct parastate *s)
|
|||
return result;
|
||||
}
|
||||
|
||||
static void mnotify(CURLM *multi, unsigned int notification,
|
||||
CURL *easy, void *user_data)
|
||||
{
|
||||
struct parastate *s = user_data;
|
||||
CURLcode result;
|
||||
|
||||
(void)multi;
|
||||
(void)easy;
|
||||
|
||||
switch(notification) {
|
||||
case CURLM_NTFY_INFO_READ:
|
||||
result = check_finished(s);
|
||||
/* remember first failure */
|
||||
if(result && !s->result)
|
||||
s->result = result;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static CURLcode parallel_transfers(CURLSH *share)
|
||||
{
|
||||
CURLcode result;
|
||||
|
|
@ -1775,6 +1764,10 @@ static CURLcode parallel_transfers(CURLSH *share)
|
|||
if(!s->multi)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
(void)curl_multi_setopt(s->multi, CURLMOPT_NOTIFYFUNCTION, mnotify);
|
||||
(void)curl_multi_setopt(s->multi, CURLMOPT_NOTIFYDATA, s);
|
||||
(void)curl_multi_notify_enable(s->multi, CURLM_NTFY_INFO_READ);
|
||||
|
||||
result = add_parallel_transfers(s->multi, s->share,
|
||||
&s->more_transfers, &s->added_transfers);
|
||||
if(result) {
|
||||
|
|
@ -1813,13 +1806,14 @@ static CURLcode parallel_transfers(CURLSH *share)
|
|||
s->mcode = curl_multi_poll(s->multi, NULL, 0, 1000, NULL);
|
||||
if(!s->mcode)
|
||||
s->mcode = curl_multi_perform(s->multi, &s->still_running);
|
||||
if(!s->mcode)
|
||||
result = check_finished(s);
|
||||
}
|
||||
|
||||
(void)progress_meter(s->multi, &s->start, TRUE);
|
||||
}
|
||||
|
||||
/* Result is the first failed transfer - if there was one. */
|
||||
result = s->result;
|
||||
|
||||
/* Make sure to return some kind of error if there was a multi problem */
|
||||
if(s->mcode) {
|
||||
result = (s->mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY :
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue