Skip to content

Commit

Permalink
curl_multi_get_handles: get easy handles from a multi handle
Browse files Browse the repository at this point in the history
Closes curl#11750
  • Loading branch information
bagder committed Sep 25, 2023
1 parent bb4032a commit 9ffd411
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/libcurl/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
73 changes: 73 additions & 0 deletions docs/libcurl/curl_multi_get_handles.3
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
.\" **************************************************************************
.\" * _ _ ____ _
.\" * Project ___| | | | _ \| |
.\" * / __| | | | |_) | |
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) Daniel Stenberg, <[email protected]>, 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) "
11 changes: 11 additions & 0 deletions include/curl/multi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions lib/conncache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions lib/doh.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
18 changes: 18 additions & 0 deletions lib/multi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
6 changes: 5 additions & 1 deletion lib/urldata.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions libcurl.def
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions scripts/singleuse.pl
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
'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',
Expand Down
1 change: 1 addition & 0 deletions tests/data/test1135
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 9ffd411

Please sign in to comment.