mirror of
https://github.com/curl/curl.git
synced 2026-08-25 10:33:31 +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
|
|
@ -78,6 +78,8 @@ man_MANS = \
|
|||
curl_multi_get_offt.3 \
|
||||
curl_multi_info_read.3 \
|
||||
curl_multi_init.3 \
|
||||
curl_multi_notify_disable.3 \
|
||||
curl_multi_notify_enable.3 \
|
||||
curl_multi_perform.3 \
|
||||
curl_multi_poll.3 \
|
||||
curl_multi_remove_handle.3 \
|
||||
|
|
|
|||
66
docs/libcurl/curl_multi_notify_disable.md
Normal file
66
docs/libcurl/curl_multi_notify_disable.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
---
|
||||
c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
SPDX-License-Identifier: curl
|
||||
Title: curl_multi_notify_disable
|
||||
Section: 3
|
||||
Source: libcurl
|
||||
See-also:
|
||||
- CURLMOPT_NOTIFYFUNCTION (3)
|
||||
- CURLMOPT_NOTIFYDATA (3)
|
||||
- curl_multi_notify_enable (3)
|
||||
Protocol:
|
||||
- All
|
||||
Added-in: 8.17.0
|
||||
---
|
||||
|
||||
# NAME
|
||||
|
||||
curl_multi_notify_disable - disable a notification type
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
~~~c
|
||||
#include <curl/curl.h>
|
||||
CURLMcode curl_multi_notify_disable(CURLM *multi_handle,
|
||||
unsigned int notification);
|
||||
~~~
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
Disables collecting the given notification type in the multi handle. A
|
||||
callback function installed via CURLMOPT_NOTIFYFUNCTION(3) is no longer
|
||||
called when this notification happens.
|
||||
|
||||
Only when a notification callback is installed *and* a notification
|
||||
is enabled are these collected and dispatched to the callback.
|
||||
|
||||
Several notification types can be enabled at the same time. Disabling
|
||||
an already disabled notification is not an error.
|
||||
|
||||
A notification can be enabled again via curl_multi_notify_enable(3).
|
||||
|
||||
# %PROTOCOLS%
|
||||
|
||||
# EXAMPLE
|
||||
|
||||
~~~c
|
||||
int main(void)
|
||||
{
|
||||
int rc;
|
||||
CURLM *multi = curl_multi_init();
|
||||
|
||||
rc = curl_multi_notify_disable(multi, CURLM_NTFY_INFO_READ);
|
||||
}
|
||||
~~~
|
||||
|
||||
# %AVAILABILITY%
|
||||
|
||||
# RETURN VALUE
|
||||
|
||||
This function returns a CURLMcode indicating success or error.
|
||||
|
||||
CURLM_OK (0) means everything was OK, non-zero means an error occurred, see
|
||||
libcurl-errors(3).
|
||||
|
||||
The return code is for the whole multi stack. Problems still might have
|
||||
occurred on individual transfers even when one of these functions return OK.
|
||||
66
docs/libcurl/curl_multi_notify_enable.md
Normal file
66
docs/libcurl/curl_multi_notify_enable.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
---
|
||||
c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
SPDX-License-Identifier: curl
|
||||
Title: curl_multi_notify_enable
|
||||
Section: 3
|
||||
Source: libcurl
|
||||
See-also:
|
||||
- CURLMOPT_NOTIFYFUNCTION (3)
|
||||
- CURLMOPT_NOTIFYDATA (3)
|
||||
- curl_multi_notify_disable (3)
|
||||
Protocol:
|
||||
- All
|
||||
Added-in: 8.17.0
|
||||
---
|
||||
|
||||
# NAME
|
||||
|
||||
curl_multi_notify_enable - enable a notification type
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
~~~c
|
||||
#include <curl/curl.h>
|
||||
CURLMcode curl_multi_notify_enable(CURLM *multi_handle,
|
||||
unsigned int notification);
|
||||
~~~
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
Enables collecting the given notification type in the multi handle. A
|
||||
callback function installed via CURLMOPT_NOTIFYFUNCTION(3) is called
|
||||
when this notification happens.
|
||||
|
||||
Only when a notification callback is installed *and* a notification
|
||||
is enabled are these collected and dispatched to the callback.
|
||||
|
||||
Several notification types can be enabled at the same time. Enabling
|
||||
an already enabled notification is not an error.
|
||||
|
||||
A notification can be disabled again via curl_multi_notify_disable(3).
|
||||
|
||||
# %PROTOCOLS%
|
||||
|
||||
# EXAMPLE
|
||||
|
||||
~~~c
|
||||
int main(void)
|
||||
{
|
||||
int rc;
|
||||
CURLM *multi = curl_multi_init();
|
||||
|
||||
rc = curl_multi_notify_enable(multi, CURLM_NTFY_INFO_READ);
|
||||
}
|
||||
~~~
|
||||
|
||||
# %AVAILABILITY%
|
||||
|
||||
# RETURN VALUE
|
||||
|
||||
This function returns a CURLMcode indicating success or error.
|
||||
|
||||
CURLM_OK (0) means everything was OK, non-zero means an error occurred, see
|
||||
libcurl-errors(3).
|
||||
|
||||
The return code is for the whole multi stack. Problems still might have
|
||||
occurred on individual transfers even when one of these functions return OK.
|
||||
|
|
@ -72,6 +72,14 @@ Max simultaneously open connections. See CURLMOPT_MAX_TOTAL_CONNECTIONS(3)
|
|||
|
||||
Signal that the network has changed. See CURLMOPT_NETWORK_CHANGED(3)
|
||||
|
||||
## CURLMOPT_NOTIFYDATA
|
||||
|
||||
Custom pointer passed to the notify callback. See CURLMOPT_NOTIFYDATA(3)
|
||||
|
||||
## CURLMOPT_NOTIFYFUNCTION
|
||||
|
||||
Callback that receives notifications. See CURLMOPT_NOTIFYFUNCTION(3)
|
||||
|
||||
## CURLMOPT_PIPELINING
|
||||
|
||||
Enable HTTP multiplexing. See CURLMOPT_PIPELINING(3)
|
||||
|
|
|
|||
72
docs/libcurl/opts/CURLMOPT_NOTIFYDATA.md
Normal file
72
docs/libcurl/opts/CURLMOPT_NOTIFYDATA.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
---
|
||||
c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
SPDX-License-Identifier: curl
|
||||
Title: CURLMOPT_NOTIFYDATA
|
||||
Section: 3
|
||||
Source: libcurl
|
||||
See-also:
|
||||
- CURLMOPT_NOTIFYFUNCTION (3)
|
||||
- curl_multi_notify_disable (3)
|
||||
- curl_multi_notify_enable (3)
|
||||
Protocol:
|
||||
- All
|
||||
Added-in: 8.17.0
|
||||
---
|
||||
|
||||
# NAME
|
||||
|
||||
CURLMOPT_NOTIFYDATA - custom pointer passed to the notification callback
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
~~~c
|
||||
#include <curl/curl.h>
|
||||
|
||||
CURLMcode curl_multi_setopt(CURLM *handle, CURLMOPT_NOTIFYDATA, void *pointer);
|
||||
~~~
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
A data *pointer* to pass to the notification callback set with the
|
||||
CURLMOPT_NOTIFYFUNCTION(3) option.
|
||||
|
||||
This pointer is not touched by libcurl but is only passed in as the
|
||||
notification callback's **clientp** argument.
|
||||
|
||||
# DEFAULT
|
||||
|
||||
NULL
|
||||
|
||||
# %PROTOCOLS%
|
||||
|
||||
# EXAMPLE
|
||||
|
||||
~~~c
|
||||
struct priv {
|
||||
void *ours;
|
||||
};
|
||||
|
||||
static void ntfy_cb(CURLM *multi, unsigned int notification,
|
||||
CURL *easy, void *ntfyp)
|
||||
{
|
||||
struct priv *p = ntfyp;
|
||||
printf("my ptr: %p\n", p->ours);
|
||||
/* ... */
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct priv setup;
|
||||
CURLM *multi = curl_multi_init();
|
||||
/* ... use socket callback and custom pointer */
|
||||
curl_multi_setopt(multi, CURLMOPT_NOTIFYFUNCTION, ntfy_cb);
|
||||
curl_multi_setopt(multi, CURLMOPT_NOTIFYDATA, &setup);
|
||||
curl_multi_notify_enable(multi, CURLM_NTFY_INFO_READ);
|
||||
}
|
||||
~~~
|
||||
|
||||
# %AVAILABILITY%
|
||||
|
||||
# RETURN VALUE
|
||||
|
||||
Returns CURLM_OK.
|
||||
129
docs/libcurl/opts/CURLMOPT_NOTIFYFUNCTION.md
Normal file
129
docs/libcurl/opts/CURLMOPT_NOTIFYFUNCTION.md
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
---
|
||||
c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
SPDX-License-Identifier: curl
|
||||
Title: CURLMOPT_NOTIFYFUNCTION
|
||||
Section: 3
|
||||
Source: libcurl
|
||||
See-also:
|
||||
- CURLMOPT_NOTIFYDATA (3)
|
||||
- curl_multi_socket_action (3)
|
||||
- curl_multi_notify_disable (3)
|
||||
- curl_multi_notify_enable (3)
|
||||
Protocol:
|
||||
- All
|
||||
Added-in: 8.17.0
|
||||
---
|
||||
|
||||
# NAME
|
||||
|
||||
CURLMOPT_NOTIFYFUNCTION - callback receiving notifications
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
~~~c
|
||||
#include <curl/curl.h>
|
||||
|
||||
void ntfy_callback(CURLM *multi, /* multi handle */
|
||||
unsigned int notification, /* notification type */
|
||||
CURL *easy, /* easy handle */
|
||||
void *ntfyp); /* private ntfy pointer */
|
||||
|
||||
CURLMcode curl_multi_setopt(CURLM *handle, CURLMOPT_NOTIFYFUNCTION, ntfy_callback);
|
||||
~~~
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
Pass a pointer to your callback function, which should match the prototype
|
||||
shown above.
|
||||
|
||||
When the multi handle processes transfers, changes can be observed
|
||||
by receiving notifications about them. This can eliminate the need to
|
||||
constantly interrogate the multi handle to observe such changes to
|
||||
act on them.
|
||||
|
||||
Notifications are collected and dispatched to the application's callback
|
||||
function at an appropriate time.
|
||||
|
||||
The notify callback is different from other callbacks in that it
|
||||
can use more libcurl API functions. Apart from curl_multi_perform(3),
|
||||
curl_multi_socket(3), curl_multi_socket_action(3), curl_multi_socket_all(3)
|
||||
and curl_multi_cleanup(3) it may call all other methods on the
|
||||
multi and easy handles. This includes adding and removing easy
|
||||
handles to/from the multi handle.
|
||||
|
||||
This callback may get invoked at any time when interacting with libcurl.
|
||||
This may even happen after all transfers are done and *may also*
|
||||
happen *during* a call to curl_multi_cleanup(3) when cached connections
|
||||
are shut down.
|
||||
|
||||
# CALLBACK ARGUMENTS
|
||||
|
||||
*multi* identifies the multi handle that triggered the notification.
|
||||
|
||||
**notification** is the type of notification, e.g. what happened. The
|
||||
following types are available:
|
||||
|
||||
## CURLM_NTFY_INFO_READ
|
||||
|
||||
When enabled via curl_multi_notify_enable(3), this informs the application
|
||||
that there are new messages to be processed via curl_multi_info_read(3).
|
||||
|
||||
This notification happens whenever a message is added to an empty
|
||||
message stack in the multi handle and not for subsequent additions. The
|
||||
notification callback is then expected to read all available message,
|
||||
emptying the stack, so a subsequent addition triggers the notification
|
||||
again.
|
||||
|
||||
The *easy* handle passed is an internal handle.
|
||||
|
||||
## CURLM_NTFY_EASY_DONE
|
||||
|
||||
When enabled via curl_multi_notify_enable(3), this notification is triggered
|
||||
when a an easy handle has finished. This happens both for
|
||||
successful and failed transfers.
|
||||
|
||||
The *easy* handle passed is the transfer that is done. This *may* be
|
||||
an internal handle when DoH or other features are used.
|
||||
|
||||
*easy* identifies the transfer involved. This may be one of the
|
||||
application's own easy handle or an internal handle.
|
||||
|
||||
**ntfyp** is set with CURLMOPT_NOTIFYDATA(3).
|
||||
|
||||
# DEFAULT
|
||||
|
||||
NULL (no callback)
|
||||
|
||||
# %PROTOCOLS%
|
||||
|
||||
# EXAMPLE
|
||||
|
||||
~~~c
|
||||
struct priv {
|
||||
void *ours;
|
||||
};
|
||||
|
||||
static void ntfy_cb(CURLM *multi, unsigned int notification,
|
||||
CURL *easy, void *ntfyp)
|
||||
{
|
||||
struct priv *p = ntfyp;
|
||||
printf("my ptr: %p\n", p->ours);
|
||||
/* ... */
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct priv setup;
|
||||
CURLM *multi = curl_multi_init();
|
||||
/* ... use socket callback and custom pointer */
|
||||
curl_multi_setopt(multi, CURLMOPT_NOTIFYFUNCTION, ntfy_cb);
|
||||
curl_multi_setopt(multi, CURLMOPT_NOTIFYDATA, &setup);
|
||||
curl_multi_notify_enable(multi, CURLM_NTFY_INFO_READ);
|
||||
}
|
||||
~~~
|
||||
|
||||
# %AVAILABILITY%
|
||||
|
||||
# RETURN VALUE
|
||||
|
||||
Returns CURLM_OK.
|
||||
|
|
@ -114,6 +114,8 @@ man_MANS = \
|
|||
CURLMOPT_MAX_TOTAL_CONNECTIONS.3 \
|
||||
CURLMOPT_MAXCONNECTS.3 \
|
||||
CURLMOPT_NETWORK_CHANGED.3 \
|
||||
CURLMOPT_NOTIFYDATA.3 \
|
||||
CURLMOPT_NOTIFYFUNCTION.3 \
|
||||
CURLMOPT_PIPELINING.3 \
|
||||
CURLMOPT_PIPELINING_SERVER_BL.3 \
|
||||
CURLMOPT_PIPELINING_SITE_BL.3 \
|
||||
|
|
|
|||
|
|
@ -545,6 +545,8 @@ CURLM_BAD_SOCKET 7.15.4
|
|||
CURLM_CALL_MULTI_PERFORM 7.9.6
|
||||
CURLM_CALL_MULTI_SOCKET 7.15.5
|
||||
CURLM_INTERNAL_ERROR 7.9.6
|
||||
CURLM_NTFY_EASY_DONE 8.17.0
|
||||
CURLM_NTFY_INFO_READ 8.17.0
|
||||
CURLM_OK 7.9.6
|
||||
CURLM_OUT_OF_MEMORY 7.9.6
|
||||
CURLM_RECURSIVE_API_CALL 7.59.0
|
||||
|
|
@ -568,6 +570,8 @@ CURLMOPT_MAX_PIPELINE_LENGTH 7.30.0
|
|||
CURLMOPT_MAX_TOTAL_CONNECTIONS 7.30.0
|
||||
CURLMOPT_MAXCONNECTS 7.16.3
|
||||
CURLMOPT_NETWORK_CHANGED 8.16.0
|
||||
CURLMOPT_NOTIFYDATA 8.17.0
|
||||
CURLMOPT_NOTIFYFUNCTION 8.17.0
|
||||
CURLMOPT_PIPELINING 7.16.0
|
||||
CURLMOPT_PIPELINING_SERVER_BL 7.30.0
|
||||
CURLMOPT_PIPELINING_SITE_BL 7.30.0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue