curl_multi_get_handles: get easy handles from a multi handle
Closes #11750
This commit is contained in:
Родитель
bb4032a152
Коммит
9ffd411735
|
@ -73,6 +73,7 @@ man_MANS = \
|
|||
curl_multi_assign.3 \
|
||||
curl_multi_cleanup.3 \
|
||||
curl_multi_fdset.3 \
|
||||
curl_multi_get_handles.3 \
|
||||
curl_multi_info_read.3 \
|
||||
curl_multi_init.3 \
|
||||
curl_multi_perform.3 \
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
.\" **************************************************************************
|
||||
.\" * _ _ ____ _
|
||||
.\" * Project ___| | | | _ \| |
|
||||
.\" * / __| | | | |_) | |
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 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
|
||||
.\" * are also available at https://curl.se/docs/copyright.html.
|
||||
.\" *
|
||||
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
.\" * copies of the Software, and permit persons to whom the Software is
|
||||
.\" * furnished to do so, under the terms of the COPYING file.
|
||||
.\" *
|
||||
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
.\" * KIND, either express or implied.
|
||||
.\" *
|
||||
.\" * SPDX-License-Identifier: curl
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.TH curl_multi_get_handles 3 "28 August 2023" "libcurl" "libcurl"
|
||||
.SH NAME
|
||||
curl_multi_get_handles - returns all added easy handles
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <curl/curl.h>
|
||||
|
||||
CURL **curl_multi_get_handles(CURLM *multi_handle);
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
Returns an array with pointers to all added easy handles. The end of the list
|
||||
is marked with a NULL pointer.
|
||||
|
||||
Even if there is not a single easy handle added, this still returns an array
|
||||
but with only a single NULL pointer entry.
|
||||
|
||||
The returned array contains all the handles that are present at the time of
|
||||
the call. As soon as a handle has been removed from or a handle has been added
|
||||
to the multi handle after the handle array was returned, the two data points
|
||||
are out of sync.
|
||||
|
||||
The order of the easy handles within the array is not guaranteed.
|
||||
|
||||
The returned array must be freed with a call to \fIcurl_free(3)\fP after use.
|
||||
.SH EXAMPLE
|
||||
.nf
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
/* add a transfer */
|
||||
curl_multi_add_handle(multi_handle, http_handle);
|
||||
|
||||
/* extract all added handles */
|
||||
CURL **list = curl_multi_get_handles(multi_handle);
|
||||
|
||||
if(list) {
|
||||
/* remove all added handles */
|
||||
for(i = 0; list[i]; i++) {
|
||||
curl_multi_remove_handle(multi_handle, list[i]);
|
||||
}
|
||||
curl_free(list);
|
||||
}
|
||||
.fi
|
||||
.SH AVAILABILITY
|
||||
Added in 8.4.0
|
||||
.SH RETURN VALUE
|
||||
Returns NULL on failure. Otherwise it returns a pointer to an allocated array.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_multi_cleanup "(3)," curl_multi_init "(3), "
|
||||
.BR curl_multi_add_handle "(3), " curl_multi_remove_handle "(3) "
|
|
@ -426,6 +426,17 @@ CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
|
|||
CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
|
||||
curl_socket_t sockfd, void *sockp);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_get_handles()
|
||||
*
|
||||
* Desc: Returns an allocated array holding all handles currently added to
|
||||
* the multi handle. Marks the final entry with a NULL pointer. If
|
||||
* there is no easy handle added to the multi handle, this function
|
||||
* returns an array with the first entry as a NULL pointer.
|
||||
*
|
||||
* Returns: NULL on failure, otherwise a CURL **array pointer
|
||||
*/
|
||||
CURL_EXTERN CURL **curl_multi_get_handles(CURLM *multi_handle);
|
||||
|
||||
/*
|
||||
* Name: curl_push_callback
|
||||
|
|
|
@ -107,6 +107,7 @@ int Curl_conncache_init(struct conncache *connc, int size)
|
|||
connc->closure_handle = curl_easy_init();
|
||||
if(!connc->closure_handle)
|
||||
return 1; /* bad */
|
||||
connc->closure_handle->internal = true;
|
||||
|
||||
Curl_hash_init(&connc->hash, size, Curl_hash_str,
|
||||
Curl_str_key_compare, free_bundle_hash_entry);
|
||||
|
|
|
@ -242,6 +242,7 @@ static CURLcode dohprobe(struct Curl_easy *data,
|
|||
/* pass in the struct pointer via a local variable to please coverity and
|
||||
the gcc typecheck helpers */
|
||||
struct dynbuf *resp = &p->serverdoh;
|
||||
doh->internal = true;
|
||||
ERROR_CHECK_SETOPT(CURLOPT_URL, url);
|
||||
ERROR_CHECK_SETOPT(CURLOPT_DEFAULT_PROTOCOL, "https");
|
||||
ERROR_CHECK_SETOPT(CURLOPT_WRITEFUNCTION, doh_write_cb);
|
||||
|
|
18
lib/multi.c
18
lib/multi.c
|
@ -3788,3 +3788,21 @@ unsigned int Curl_multi_max_concurrent_streams(struct Curl_multi *multi)
|
|||
DEBUGASSERT(multi);
|
||||
return multi->max_concurrent_streams;
|
||||
}
|
||||
|
||||
struct Curl_easy **curl_multi_get_handles(struct Curl_multi *multi)
|
||||
{
|
||||
struct Curl_easy **a = malloc(sizeof(struct Curl_easy *) *
|
||||
(multi->num_easy + 1));
|
||||
if(a) {
|
||||
int i = 0;
|
||||
struct Curl_easy *e = multi->easyp;
|
||||
while(e) {
|
||||
DEBUGASSERT(i < multi->num_easy);
|
||||
if(!e->internal)
|
||||
a[i++] = e;
|
||||
e = e->next;
|
||||
}
|
||||
a[i] = NULL; /* last entry is a NULL */
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
|
|
@ -1950,7 +1950,7 @@ struct Curl_easy {
|
|||
other using the same cache. For easier tracking
|
||||
in log output.
|
||||
This may wrap around after LONG_MAX to 0 again, so it
|
||||
has no uniqueness guarantuee for very large processings. */
|
||||
has no uniqueness guarantee for very large processings. */
|
||||
curl_off_t id;
|
||||
|
||||
/* first, two fields for the linked list of these */
|
||||
|
@ -2013,6 +2013,10 @@ struct Curl_easy {
|
|||
#ifdef USE_HYPER
|
||||
struct hyptransfer hyp;
|
||||
#endif
|
||||
|
||||
/* internal: true if this easy handle was created for internal use and the
|
||||
user does not have ownership of the handle. */
|
||||
bool internal;
|
||||
};
|
||||
|
||||
#define LIBCURL_NAME "libcurl"
|
||||
|
|
|
@ -51,6 +51,7 @@ curl_multi_add_handle
|
|||
curl_multi_assign
|
||||
curl_multi_cleanup
|
||||
curl_multi_fdset
|
||||
curl_multi_get_handles
|
||||
curl_multi_info_read
|
||||
curl_multi_init
|
||||
curl_multi_perform
|
||||
|
|
|
@ -96,6 +96,7 @@ my %api = (
|
|||
'curl_multi_assign' => 'API',
|
||||
'curl_multi_cleanup' => 'API',
|
||||
'curl_multi_fdset' => 'API',
|
||||
'curl_multi_get_handles' => 'API',
|
||||
'curl_multi_info_read' => 'API',
|
||||
'curl_multi_init' => 'API',
|
||||
'curl_multi_perform' => 'API',
|
||||
|
|
|
@ -106,6 +106,7 @@ curl_multi_socket_all
|
|||
curl_multi_timeout
|
||||
curl_multi_setopt
|
||||
curl_multi_assign
|
||||
curl_multi_get_handles
|
||||
curl_pushheader_bynum
|
||||
curl_pushheader_byname
|
||||
curl_easy_option_by_name
|
||||
|
|
Загрузка…
Ссылка в новой задаче