-
-
Notifications
You must be signed in to change notification settings - Fork 6.7k
multi transfer book keeping using mid #16761
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70480f8
to
a5035ae
Compare
Change multi's book keeping of transfers to no longer use lists, but a special table and bitsets for unsigned int values. `multi-xfers` is the `uint_tbl` where `multi_add_handle()` inserts a new transfer which assigns it a unique identifier `mid`. Use bitsets to keep track of transfers that are in state "process" or "pending" or "msgsent". Use sparse bitsets to replace `conn->easyq` and event handlings tracking of transfers per socket. Instead of pointers, keep the mids involved. Provide base data structures and document them in docs/internal: * `uint_tbl`: a table of transfers with `mid` as lookup key, handing out a mid for adds between 0 - capacity. * `uint_bset`: a bitset keeping unsigned ints from 0 - capacity. * `uint_spbset`: a sparse bitset for keeping a small number of unsigned int values * `uint_hash`: for associating `mid`s with a pointer. This makes the `mid` the recommended way to refer to transfers inside the same multi without risk of running into a UAF. Modifying table and bitsets is safe while iterating over them. Overall memory requirements are lower as with the double linked list apprach.
Use UINT_MAX everywhere as invalid mid number, replacing extra define Add more tracing of multi_add/remove/cleanup with mid and counters
bagder
reviewed
Apr 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, I only spotted very minor nits...
nbaws
pushed a commit
to nbaws/curl
that referenced
this pull request
Apr 26, 2025
Change multi's book keeping of transfers to no longer use lists, but a special table and bitsets for unsigned int values. `multi-xfers` is the `uint_tbl` where `multi_add_handle()` inserts a new transfer which assigns it a unique identifier `mid`. Use bitsets to keep track of transfers that are in state "process" or "pending" or "msgsent". Use sparse bitsets to replace `conn->easyq` and event handlings tracking of transfers per socket. Instead of pointers, keep the mids involved. Provide base data structures and document them in docs/internal: * `uint_tbl`: a table of transfers with `mid` as lookup key, handing out a mid for adds between 0 - capacity. * `uint_bset`: a bitset keeping unsigned ints from 0 - capacity. * `uint_spbset`: a sparse bitset for keeping a small number of unsigned int values * `uint_hash`: for associating `mid`s with a pointer. This makes the `mid` the recommended way to refer to transfers inside the same multi without risk of running into a UAF. Modifying table and bitsets is safe while iterating over them. Overall memory requirements are lower as with the double linked list apprach. Closes curl#16761
nbaws
pushed a commit
to nbaws/curl
that referenced
this pull request
Apr 26, 2025
Change multi's book keeping of transfers to no longer use lists, but a special table and bitsets for unsigned int values. `multi-xfers` is the `uint_tbl` where `multi_add_handle()` inserts a new transfer which assigns it a unique identifier `mid`. Use bitsets to keep track of transfers that are in state "process" or "pending" or "msgsent". Use sparse bitsets to replace `conn->easyq` and event handlings tracking of transfers per socket. Instead of pointers, keep the mids involved. Provide base data structures and document them in docs/internal: * `uint_tbl`: a table of transfers with `mid` as lookup key, handing out a mid for adds between 0 - capacity. * `uint_bset`: a bitset keeping unsigned ints from 0 - capacity. * `uint_spbset`: a sparse bitset for keeping a small number of unsigned int values * `uint_hash`: for associating `mid`s with a pointer. This makes the `mid` the recommended way to refer to transfers inside the same multi without risk of running into a UAF. Modifying table and bitsets is safe while iterating over them. Overall memory requirements are lower as with the double linked list apprach. Closes curl#16761
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
CI
Continuous Integration
feature-window
A merge of this requires an open feature window
libcurl API
tests
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Change multi's book keeping of transfers to no longer use lists, but a special table and bitsets for unsigned int values.
multi->xfers
is theuint_tbl
wheremulti_add_handle()
inserts a new transfer which assigns it a unique identifiermid
. Use bitsets to keep track of transfers that are in state "process" or "pending" or "msgsent".Use sparse bitsets to replace
conn->easyq
and event handlings tracking of transfers per socket.Provide base data structures and document them in docs/internal:
uint_tbl
: a table of transfers withmid
as lookup key, handing out a mid for adds between 0 - capacity.uint_bset
: a bitset keeping unsigned ints from 0 - capacity.uint_spbset
: a sparse bitset for keeping a small number of unsigned int valuesuint_hash
: for associatingmid
s with a pointer.This makes the
mid
the recommended way to refer to transfers inside the same multi without risk of running into a UAF.Modifying table and bitsets is safe while iterating over them. Overall memory requirements are lower than with the double linked list apprach.
memory
To keep track of 1000 transfers, the dominating factor before were 2
struct Curl_llist_node
in eachCurl_easy
. Each occupies 32 bytes each, so 64 KB for 1000 easy handles.With this PR, we have one table and 3 bitsets, which are kept 25% free. The table uses 8 bytes per possible entry, so ~10 KB for 1300 rows of capacity. A bitset for numbers 0-1299 occupies 168 bytes, which makes ~540 bytes for all three. Plus a "sparse" bitset per connection. For the case that each transfer has its own connection, that adds 32 bytes for each one.
*) the usual rounding errors with 1000 ~= 1024 apply.😌