mirror of
https://github.com/curl/curl.git
synced 2026-01-18 17:21:26 +01:00
lib: change uint sets to operate on uint32_t
- clarify names and change types - make multi's `mid` a uint32_t - update documentation Closes #19695
This commit is contained in:
committed by
Daniel Stenberg
parent
bb63518ba7
commit
4701a6d2ae
@@ -4,23 +4,23 @@ Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
SPDX-License-Identifier: curl
|
||||
-->
|
||||
|
||||
# Unsigned Int Sets
|
||||
# `uint32_t` Sets
|
||||
|
||||
The multi handle tracks added easy handles via an unsigned int
|
||||
it calls an `mid`. There are four data structures for unsigned int
|
||||
The multi handle tracks added easy handles via an `uint32_t`
|
||||
it calls an `mid`. There are four data structures for `uint32_t`
|
||||
optimized for the multi use case.
|
||||
|
||||
## `uint_tbl`
|
||||
## `uint32_tbl`
|
||||
|
||||
`uint_table`, implemented in `uint-table.[ch]` manages an array
|
||||
of `void *`. The unsigned int are the index into this array. It is
|
||||
`uint32_table`, implemented in `uint-table.[ch]` manages an array
|
||||
of `void *`. The `uint32_t` is the index into this array. It is
|
||||
created with a *capacity* which can be *resized*. The table assigns
|
||||
the index when a `void *` is *added*. It keeps track of the last
|
||||
assigned index and uses the next available larger index for a
|
||||
subsequent add. Reaching *capacity* it wraps around.
|
||||
|
||||
The table *can not* store `NULL` values. The largest possible index
|
||||
is `UINT_MAX - 1`.
|
||||
is `UINT32_MAX - 1`.
|
||||
|
||||
The table is iterated over by asking for the *first* existing index,
|
||||
meaning the smallest number that has an entry, if the table is not
|
||||
@@ -29,10 +29,10 @@ iteration step. It does not matter if the previous index is still
|
||||
in the table. Sample code for a table iteration would look like this:
|
||||
|
||||
```c
|
||||
unsigned int mid;
|
||||
uint32_t int mid;
|
||||
void *entry;
|
||||
|
||||
if(Curl_uint_tbl_first(tbl, &mid, &entry)) {
|
||||
if(Curl_uint32_tbl_first(tbl, &mid, &entry)) {
|
||||
do {
|
||||
/* operate on entry with index mid */
|
||||
}
|
||||
@@ -51,7 +51,7 @@ This iteration has the following properties:
|
||||
### Memory
|
||||
|
||||
For storing 1000 entries, the table would allocate one block of 8KB on a 64-bit system,
|
||||
plus the 2 pointers and 3 unsigned int in its base `struct uint_tbl`. A resize
|
||||
plus the 2 pointers and 3 `uint32_t` in its base `struct uint32_tbl`. A resize
|
||||
allocates a completely new pointer array, copy the existing entries and free the previous one.
|
||||
|
||||
### Performance
|
||||
@@ -77,17 +77,17 @@ For these reasons, the simple implementation was preferred. Should this become
|
||||
a concern, there are options like "free index lists" or, alternatively, an internal
|
||||
bitset that scans better.
|
||||
|
||||
## `uint_bset`
|
||||
## `uint32_bset`
|
||||
|
||||
A bitset for unsigned integers, allowing fast add/remove operations. It is initialized
|
||||
A bitset for `uint32_t` values, allowing fast add/remove operations. It is initialized
|
||||
with a *capacity*, meaning it can store only the numbers in the range `[0, capacity-1]`.
|
||||
It can be *resized* and safely *iterated*. `uint_bset` is designed to operate in combination with `uint_tbl`.
|
||||
It can be *resized* and safely *iterated*. `uint32_bset` is designed to operate in combination with `uint_tbl`.
|
||||
|
||||
The bitset keeps an array of `curl_uint64_t`. The first array entry keeps the numbers 0 to 63, the
|
||||
The bitset keeps an array of `uint64_t`. The first array entry keeps the numbers 0 to 63, the
|
||||
second 64 to 127 and so on. A bitset with capacity 1024 would therefore allocate an array
|
||||
of 16 64-bit values (128 bytes). Operations for an unsigned int divide it by 64 for the array index and then check/set/clear the bit of the remainder.
|
||||
|
||||
Iterator works the same as with `uint_tbl`: ask the bitset for the *first* number present and
|
||||
Iterator works the same as with `uint32_tbl`: ask the bitset for the *first* number present and
|
||||
then use that to get the *next* higher number present. Like the table, this safe for
|
||||
adds/removes and growing the set while iterating.
|
||||
|
||||
@@ -102,14 +102,14 @@ Operations for add/remove/check are O(1). Iteration needs to scan for the next b
|
||||
number of scans is small (see memory footprint) and, for checking bits, many compilers
|
||||
offer primitives for special CPU instructions.
|
||||
|
||||
## `uint_spbset`
|
||||
## `uint32_spbset`
|
||||
|
||||
While the memory footprint of `uint_bset` is good, it still needs 5KB to store the single number 40000. This
|
||||
While the memory footprint of `uint32_bset` is good, it still needs 5KB to store the single number 40000. This
|
||||
is not optimal when many are needed. For example, in event based processing, each socket needs to
|
||||
keep track of the transfers involved. There are many sockets potentially, but each one mostly tracks
|
||||
a single transfer or few (on HTTP/2 connection borderline up to 100).
|
||||
|
||||
For such uses cases, the `uint_spbset` is intended: track a small number of unsigned int, potentially
|
||||
For such uses cases, the `uint32_spbset` is intended: track a small number of unsigned int, potentially
|
||||
rather "close" together. It keeps "chunks" with an offset and has no capacity limit.
|
||||
|
||||
Example: adding the number 40000 to an empty sparse bitset would have one chunk with offset 39936, keeping
|
||||
@@ -121,8 +121,8 @@ would need to be allocated and linked, resulting in overall 4 KB of memory used.
|
||||
|
||||
Iterating a sparse bitset works the same as for bitset and table.
|
||||
|
||||
## `uint_hash`
|
||||
## `uint32_hash`
|
||||
|
||||
At last, there are places in libcurl such as the HTTP/2 and HTTP/3 protocol implementations that need
|
||||
to store their own data related to a transfer. `uint_hash` allows then to associate an unsigned int,
|
||||
to store their own data related to a transfer. `uint32_hash` allows then to associate an unsigned int,
|
||||
e.g. the transfer's `mid`, to their own data.
|
||||
|
||||
16
lib/doh.c
16
lib/doh.c
@@ -286,7 +286,7 @@ static CURLcode doh_probe_run(struct Curl_easy *data,
|
||||
DNStype dnstype,
|
||||
const char *host,
|
||||
const char *url, CURLM *multi,
|
||||
unsigned int *pmid)
|
||||
uint32_t *pmid)
|
||||
{
|
||||
struct Curl_easy *doh = NULL;
|
||||
CURLcode result = CURLE_OK;
|
||||
@@ -294,7 +294,7 @@ static CURLcode doh_probe_run(struct Curl_easy *data,
|
||||
struct doh_request *doh_req;
|
||||
DOHcode d;
|
||||
|
||||
*pmid = UINT_MAX;
|
||||
*pmid = UINT32_MAX;
|
||||
|
||||
doh_req = calloc(1, sizeof(*doh_req));
|
||||
if(!doh_req)
|
||||
@@ -472,7 +472,7 @@ CURLcode Curl_doh(struct Curl_easy *data, const char *hostname,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
for(i = 0; i < DOH_SLOT_COUNT; ++i) {
|
||||
dohp->probe_resp[i].probe_mid = UINT_MAX;
|
||||
dohp->probe_resp[i].probe_mid = UINT32_MAX;
|
||||
curlx_dyn_init(&dohp->probe_resp[i].body, DYN_DOH_RESPONSE);
|
||||
}
|
||||
|
||||
@@ -1222,8 +1222,8 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
|
||||
if(!dohp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(dohp->probe_resp[DOH_SLOT_IPV4].probe_mid == UINT_MAX &&
|
||||
dohp->probe_resp[DOH_SLOT_IPV6].probe_mid == UINT_MAX) {
|
||||
if(dohp->probe_resp[DOH_SLOT_IPV4].probe_mid == UINT32_MAX &&
|
||||
dohp->probe_resp[DOH_SLOT_IPV6].probe_mid == UINT32_MAX) {
|
||||
failf(data, "Could not DoH-resolve: %s", dohp->host);
|
||||
return CONN_IS_PROXIED(data->conn) ? CURLE_COULDNT_RESOLVE_PROXY :
|
||||
CURLE_COULDNT_RESOLVE_HOST;
|
||||
@@ -1318,13 +1318,13 @@ void Curl_doh_close(struct Curl_easy *data)
|
||||
struct doh_probes *doh = data->state.async.doh;
|
||||
if(doh && data->multi) {
|
||||
struct Curl_easy *probe_data;
|
||||
unsigned int mid;
|
||||
uint32_t mid;
|
||||
size_t slot;
|
||||
for(slot = 0; slot < DOH_SLOT_COUNT; slot++) {
|
||||
mid = doh->probe_resp[slot].probe_mid;
|
||||
if(mid == UINT_MAX)
|
||||
if(mid == UINT32_MAX)
|
||||
continue;
|
||||
doh->probe_resp[slot].probe_mid = UINT_MAX;
|
||||
doh->probe_resp[slot].probe_mid = UINT32_MAX;
|
||||
/* should have been called before data is removed from multi handle */
|
||||
DEBUGASSERT(data->multi);
|
||||
probe_data = data->multi ? Curl_multi_get_easy(data->multi, mid) :
|
||||
|
||||
@@ -96,7 +96,7 @@ struct doh_request {
|
||||
};
|
||||
|
||||
struct doh_response {
|
||||
unsigned int probe_mid;
|
||||
uint32_t probe_mid;
|
||||
struct dynbuf body;
|
||||
DNStype dnstype;
|
||||
CURLcode result;
|
||||
|
||||
@@ -988,8 +988,8 @@ CURL *curl_easy_duphandle(CURL *d)
|
||||
outcurl->state.lastconnect_id = -1;
|
||||
outcurl->state.recent_conn_id = -1;
|
||||
outcurl->id = -1;
|
||||
outcurl->mid = UINT_MAX;
|
||||
outcurl->master_mid = UINT_MAX;
|
||||
outcurl->mid = UINT32_MAX;
|
||||
outcurl->master_mid = UINT32_MAX;
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
Curl_llist_init(&outcurl->state.httphdrs, NULL);
|
||||
@@ -1126,7 +1126,7 @@ void curl_easy_reset(CURL *d)
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_DIGEST_AUTH)
|
||||
Curl_http_auth_cleanup_digest(data);
|
||||
#endif
|
||||
data->master_mid = UINT_MAX;
|
||||
data->master_mid = UINT32_MAX;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
10
lib/http2.c
10
lib/http2.c
@@ -140,7 +140,7 @@ static void cf_h2_ctx_init(struct cf_h2_ctx *ctx, bool via_h1_upgrade)
|
||||
Curl_bufq_initp(&ctx->inbufq, &ctx->stream_bufcp, H2_NW_RECV_CHUNKS, 0);
|
||||
Curl_bufq_initp(&ctx->outbufq, &ctx->stream_bufcp, H2_NW_SEND_CHUNKS, 0);
|
||||
curlx_dyn_init(&ctx->scratch, CURL_MAX_HTTP_HEADER);
|
||||
Curl_uint_hash_init(&ctx->streams, 63, h2_stream_hash_free);
|
||||
Curl_uint32_hash_init(&ctx->streams, 63, h2_stream_hash_free);
|
||||
ctx->remote_max_sid = 2147483647;
|
||||
ctx->via_h1_upgrade = via_h1_upgrade;
|
||||
#ifdef DEBUGBUILD
|
||||
@@ -165,7 +165,7 @@ static void cf_h2_ctx_free(struct cf_h2_ctx *ctx)
|
||||
Curl_bufq_free(&ctx->outbufq);
|
||||
Curl_bufcp_free(&ctx->stream_bufcp);
|
||||
curlx_dyn_free(&ctx->scratch);
|
||||
Curl_uint_hash_destroy(&ctx->streams);
|
||||
Curl_uint32_hash_destroy(&ctx->streams);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
free(ctx);
|
||||
@@ -269,7 +269,7 @@ struct h2_stream_ctx {
|
||||
|
||||
#define H2_STREAM_CTX(ctx,data) \
|
||||
((struct h2_stream_ctx *)( \
|
||||
data? Curl_uint_hash_get(&(ctx)->streams, (data)->mid) : NULL))
|
||||
data? Curl_uint32_hash_get(&(ctx)->streams, (data)->mid) : NULL))
|
||||
|
||||
static struct h2_stream_ctx *h2_stream_ctx_create(struct cf_h2_ctx *ctx)
|
||||
{
|
||||
@@ -426,7 +426,7 @@ static CURLcode http2_data_setup(struct Curl_cfilter *cf,
|
||||
if(!stream)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(!Curl_uint_hash_set(&ctx->streams, data->mid, stream)) {
|
||||
if(!Curl_uint32_hash_set(&ctx->streams, data->mid, stream)) {
|
||||
h2_stream_ctx_free(stream);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
@@ -466,7 +466,7 @@ static void http2_data_done(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
}
|
||||
}
|
||||
|
||||
Curl_uint_hash_remove(&ctx->streams, data->mid);
|
||||
Curl_uint32_hash_remove(&ctx->streams, data->mid);
|
||||
}
|
||||
|
||||
static int h2_client_new(struct Curl_cfilter *cf,
|
||||
|
||||
282
lib/multi.c
282
lib/multi.c
@@ -180,11 +180,11 @@ static void mstate(struct Curl_easy *data, CURLMstate state
|
||||
if(oldstate < MSTATE_DONE)
|
||||
CURLM_NTFY(data, CURLMNOTIFY_EASY_DONE);
|
||||
/* changing to COMPLETED means it is in process and needs to go */
|
||||
DEBUGASSERT(Curl_uint_bset_contains(&data->multi->process, data->mid));
|
||||
Curl_uint_bset_remove(&data->multi->process, data->mid);
|
||||
Curl_uint_bset_remove(&data->multi->pending, data->mid); /* to be sure */
|
||||
DEBUGASSERT(Curl_uint32_bset_contains(&data->multi->process, data->mid));
|
||||
Curl_uint32_bset_remove(&data->multi->process, data->mid);
|
||||
Curl_uint32_bset_remove(&data->multi->pending, data->mid); /* to be sure */
|
||||
|
||||
if(Curl_uint_bset_empty(&data->multi->process)) {
|
||||
if(Curl_uint32_bset_empty(&data->multi->process)) {
|
||||
/* free the transfer buffer when we have no more active transfers */
|
||||
multi_xfer_bufs_free(data->multi);
|
||||
}
|
||||
@@ -229,7 +229,7 @@ static void multi_addmsg(struct Curl_multi *multi, struct Curl_message *msg)
|
||||
Curl_llist_append(&multi->msglist, msg, &msg->list);
|
||||
}
|
||||
|
||||
struct Curl_multi *Curl_multi_handle(unsigned int xfer_table_size,
|
||||
struct Curl_multi *Curl_multi_handle(uint32_t xfer_table_size,
|
||||
size_t ev_hashsize, /* event hash */
|
||||
size_t chashsize, /* connection hash */
|
||||
size_t dnssize, /* dns hash */
|
||||
@@ -245,11 +245,11 @@ struct Curl_multi *Curl_multi_handle(unsigned int xfer_table_size,
|
||||
Curl_dnscache_init(&multi->dnscache, dnssize);
|
||||
Curl_mntfy_init(multi);
|
||||
Curl_multi_ev_init(multi, ev_hashsize);
|
||||
Curl_uint_tbl_init(&multi->xfers, NULL);
|
||||
Curl_uint_bset_init(&multi->process);
|
||||
Curl_uint_bset_init(&multi->dirty);
|
||||
Curl_uint_bset_init(&multi->pending);
|
||||
Curl_uint_bset_init(&multi->msgsent);
|
||||
Curl_uint32_tbl_init(&multi->xfers, NULL);
|
||||
Curl_uint32_bset_init(&multi->process);
|
||||
Curl_uint32_bset_init(&multi->dirty);
|
||||
Curl_uint32_bset_init(&multi->pending);
|
||||
Curl_uint32_bset_init(&multi->msgsent);
|
||||
Curl_hash_init(&multi->proto_hash, 23,
|
||||
Curl_hash_str, curlx_str_key_compare, ph_freeentry);
|
||||
Curl_llist_init(&multi->msglist, NULL);
|
||||
@@ -259,11 +259,11 @@ struct Curl_multi *Curl_multi_handle(unsigned int xfer_table_size,
|
||||
multi->last_timeout_ms = -1;
|
||||
|
||||
if(Curl_mntfy_resize(multi) ||
|
||||
Curl_uint_bset_resize(&multi->process, xfer_table_size) ||
|
||||
Curl_uint_bset_resize(&multi->pending, xfer_table_size) ||
|
||||
Curl_uint_bset_resize(&multi->dirty, xfer_table_size) ||
|
||||
Curl_uint_bset_resize(&multi->msgsent, xfer_table_size) ||
|
||||
Curl_uint_tbl_resize(&multi->xfers, xfer_table_size))
|
||||
Curl_uint32_bset_resize(&multi->process, xfer_table_size) ||
|
||||
Curl_uint32_bset_resize(&multi->pending, xfer_table_size) ||
|
||||
Curl_uint32_bset_resize(&multi->dirty, xfer_table_size) ||
|
||||
Curl_uint32_bset_resize(&multi->msgsent, xfer_table_size) ||
|
||||
Curl_uint32_tbl_resize(&multi->xfers, xfer_table_size))
|
||||
goto error;
|
||||
|
||||
multi->admin = curl_easy_init();
|
||||
@@ -278,8 +278,8 @@ struct Curl_multi *Curl_multi_handle(unsigned int xfer_table_size,
|
||||
if(getenv("CURL_DEBUG"))
|
||||
multi->admin->set.verbose = TRUE;
|
||||
#endif
|
||||
Curl_uint_tbl_add(&multi->xfers, multi->admin, &multi->admin->mid);
|
||||
Curl_uint_bset_add(&multi->process, multi->admin->mid);
|
||||
Curl_uint32_tbl_add(&multi->xfers, multi->admin, &multi->admin->mid);
|
||||
Curl_uint32_bset_add(&multi->process, multi->admin->mid);
|
||||
|
||||
if(Curl_cshutdn_init(&multi->cshutdn, multi))
|
||||
goto error;
|
||||
@@ -322,11 +322,11 @@ error:
|
||||
}
|
||||
Curl_mntfy_cleanup(multi);
|
||||
|
||||
Curl_uint_bset_destroy(&multi->process);
|
||||
Curl_uint_bset_destroy(&multi->dirty);
|
||||
Curl_uint_bset_destroy(&multi->pending);
|
||||
Curl_uint_bset_destroy(&multi->msgsent);
|
||||
Curl_uint_tbl_destroy(&multi->xfers);
|
||||
Curl_uint32_bset_destroy(&multi->process);
|
||||
Curl_uint32_bset_destroy(&multi->dirty);
|
||||
Curl_uint32_bset_destroy(&multi->pending);
|
||||
Curl_uint32_bset_destroy(&multi->msgsent);
|
||||
Curl_uint32_tbl_destroy(&multi->xfers);
|
||||
|
||||
free(multi);
|
||||
return NULL;
|
||||
@@ -359,12 +359,12 @@ static void multi_warn_debug(struct Curl_multi *multi, struct Curl_easy *data)
|
||||
static CURLMcode multi_xfers_add(struct Curl_multi *multi,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
unsigned int capacity = Curl_uint_tbl_capacity(&multi->xfers);
|
||||
unsigned int new_size = 0;
|
||||
uint32_t capacity = Curl_uint32_tbl_capacity(&multi->xfers);
|
||||
uint32_t new_size = 0;
|
||||
/* Prepare to make this into a CURLMOPT_MAX_TRANSFERS, because some
|
||||
* applications may want to prevent a run-away of their memory use. */
|
||||
/* UINT_MAX is our "invalid" id, do not let the table grow up to that. */
|
||||
const unsigned int max_capacity = UINT_MAX - 1;
|
||||
const uint32_t max_capacity = UINT_MAX - 1;
|
||||
|
||||
if(capacity < max_capacity) {
|
||||
/* We want `multi->xfers` to have "sufficient" free rows, so that we do
|
||||
@@ -372,9 +372,9 @@ static CURLMcode multi_xfers_add(struct Curl_multi *multi,
|
||||
* Since uint_tbl and uint_bset are quite memory efficient,
|
||||
* regard less than 25% free as insufficient.
|
||||
* (for low capacities, e.g. multi_easy, 4 or less). */
|
||||
unsigned int used = Curl_uint_tbl_count(&multi->xfers);
|
||||
unsigned int unused = capacity - used;
|
||||
unsigned int min_unused = CURLMAX(capacity >> 2, 4);
|
||||
uint32_t used = Curl_uint32_tbl_count(&multi->xfers);
|
||||
uint32_t unused = capacity - used;
|
||||
uint32_t min_unused = CURLMAX(capacity >> 2, 4);
|
||||
if(unused <= min_unused) {
|
||||
/* Make sure the uint arithmetic here works on the corner
|
||||
* cases where we are close to max_capacity or UINT_MAX */
|
||||
@@ -397,19 +397,19 @@ static CURLMcode multi_xfers_add(struct Curl_multi *multi,
|
||||
* to work properly when larger than the table, but not
|
||||
* the other way around. */
|
||||
CURL_TRC_M(data, "increasing xfer table size to %u", new_size);
|
||||
if(Curl_uint_bset_resize(&multi->process, new_size) ||
|
||||
Curl_uint_bset_resize(&multi->dirty, new_size) ||
|
||||
Curl_uint_bset_resize(&multi->pending, new_size) ||
|
||||
Curl_uint_bset_resize(&multi->msgsent, new_size) ||
|
||||
Curl_uint_tbl_resize(&multi->xfers, new_size))
|
||||
if(Curl_uint32_bset_resize(&multi->process, new_size) ||
|
||||
Curl_uint32_bset_resize(&multi->dirty, new_size) ||
|
||||
Curl_uint32_bset_resize(&multi->pending, new_size) ||
|
||||
Curl_uint32_bset_resize(&multi->msgsent, new_size) ||
|
||||
Curl_uint32_tbl_resize(&multi->xfers, new_size))
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Insert the easy into the table now */
|
||||
if(!Curl_uint_tbl_add(&multi->xfers, data, &data->mid)) {
|
||||
if(!Curl_uint32_tbl_add(&multi->xfers, data, &data->mid)) {
|
||||
/* MUST only happen when table is full */
|
||||
DEBUGASSERT(Curl_uint_tbl_capacity(&multi->xfers) <=
|
||||
Curl_uint_tbl_count(&multi->xfers));
|
||||
DEBUGASSERT(Curl_uint32_tbl_capacity(&multi->xfers) <=
|
||||
Curl_uint32_tbl_count(&multi->xfers));
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
return CURLM_OK;
|
||||
@@ -441,14 +441,14 @@ CURLMcode curl_multi_add_handle(CURLM *m, CURL *d)
|
||||
handles are still alive - but if there are none alive anymore, it is
|
||||
fine to start over and unmark the "deadness" of this handle.
|
||||
This means only the admin handle MUST be present. */
|
||||
if((Curl_uint_tbl_count(&multi->xfers) != 1) ||
|
||||
!Curl_uint_tbl_contains(&multi->xfers, 0))
|
||||
if((Curl_uint32_tbl_count(&multi->xfers) != 1) ||
|
||||
!Curl_uint32_tbl_contains(&multi->xfers, 0))
|
||||
return CURLM_ABORTED_BY_CALLBACK;
|
||||
multi->dead = FALSE;
|
||||
Curl_uint_bset_clear(&multi->process);
|
||||
Curl_uint_bset_clear(&multi->dirty);
|
||||
Curl_uint_bset_clear(&multi->pending);
|
||||
Curl_uint_bset_clear(&multi->msgsent);
|
||||
Curl_uint32_bset_clear(&multi->process);
|
||||
Curl_uint32_bset_clear(&multi->dirty);
|
||||
Curl_uint32_bset_clear(&multi->pending);
|
||||
Curl_uint32_bset_clear(&multi->msgsent);
|
||||
}
|
||||
|
||||
if(data->multi_easy) {
|
||||
@@ -492,7 +492,7 @@ CURLMcode curl_multi_add_handle(CURLM *m, CURL *d)
|
||||
#endif
|
||||
|
||||
/* add the easy handle to the process set */
|
||||
Curl_uint_bset_add(&multi->process, data->mid);
|
||||
Curl_uint32_bset_add(&multi->process, data->mid);
|
||||
++multi->xfers_alive;
|
||||
++multi->xfers_total_ever;
|
||||
|
||||
@@ -507,8 +507,8 @@ CURLMcode curl_multi_add_handle(CURLM *m, CURL *d)
|
||||
rc = Curl_update_timer(multi);
|
||||
if(rc) {
|
||||
data->multi = NULL; /* not anymore */
|
||||
Curl_uint_tbl_remove(&multi->xfers, data->mid);
|
||||
data->mid = UINT_MAX;
|
||||
Curl_uint32_tbl_remove(&multi->xfers, data->mid);
|
||||
data->mid = UINT32_MAX;
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -523,7 +523,7 @@ CURLMcode curl_multi_add_handle(CURLM *m, CURL *d)
|
||||
|
||||
CURL_TRC_M(data, "added to multi, mid=%u, running=%u, total=%u",
|
||||
data->mid, Curl_multi_xfers_running(multi),
|
||||
Curl_uint_tbl_count(&multi->xfers));
|
||||
Curl_uint32_tbl_count(&multi->xfers));
|
||||
return CURLM_OK;
|
||||
}
|
||||
|
||||
@@ -572,11 +572,11 @@ static void multi_done_locked(struct connectdata *conn,
|
||||
Curl_detach_connection(data);
|
||||
|
||||
CURL_TRC_M(data, "multi_done_locked, in use=%u",
|
||||
Curl_uint_spbset_count(&conn->xfers_attached));
|
||||
Curl_uint32_spbset_count(&conn->xfers_attached));
|
||||
if(CONN_INUSE(conn)) {
|
||||
/* Stop if still used. */
|
||||
CURL_TRC_M(data, "Connection still in use %u, no more multi_done now!",
|
||||
Curl_uint_spbset_count(&conn->xfers_attached));
|
||||
Curl_uint32_spbset_count(&conn->xfers_attached));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -740,7 +740,7 @@ CURLMcode curl_multi_remove_handle(CURLM *m, CURL *d)
|
||||
struct Curl_llist_node *e;
|
||||
CURLMcode rc;
|
||||
bool removed_timer = FALSE;
|
||||
unsigned int mid;
|
||||
uint32_t mid;
|
||||
|
||||
/* First, make some basic checks that the CURLM handle is a good handle */
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
@@ -758,11 +758,11 @@ CURLMcode curl_multi_remove_handle(CURLM *m, CURL *d)
|
||||
if(data->multi != multi)
|
||||
return CURLM_BAD_EASY_HANDLE;
|
||||
|
||||
if(data->mid == UINT_MAX) {
|
||||
if(data->mid == UINT32_MAX) {
|
||||
DEBUGASSERT(0);
|
||||
return CURLM_INTERNAL_ERROR;
|
||||
}
|
||||
if(Curl_uint_tbl_get(&multi->xfers, data->mid) != data) {
|
||||
if(Curl_uint32_tbl_get(&multi->xfers, data->mid) != data) {
|
||||
DEBUGASSERT(0);
|
||||
return CURLM_INTERNAL_ERROR;
|
||||
}
|
||||
@@ -797,7 +797,7 @@ CURLMcode curl_multi_remove_handle(CURLM *m, CURL *d)
|
||||
removed_timer = Curl_expire_clear(data);
|
||||
|
||||
/* If in `msgsent`, it was deducted from `multi->xfers_alive` already. */
|
||||
if(!Curl_uint_bset_contains(&multi->msgsent, data->mid))
|
||||
if(!Curl_uint32_bset_contains(&multi->msgsent, data->mid))
|
||||
--multi->xfers_alive;
|
||||
|
||||
Curl_wildcard_dtor(&data->wildcard);
|
||||
@@ -853,15 +853,15 @@ CURLMcode curl_multi_remove_handle(CURLM *m, CURL *d)
|
||||
|
||||
/* clear the association to this multi handle */
|
||||
mid = data->mid;
|
||||
DEBUGASSERT(Curl_uint_tbl_contains(&multi->xfers, mid));
|
||||
Curl_uint_tbl_remove(&multi->xfers, mid);
|
||||
Curl_uint_bset_remove(&multi->process, mid);
|
||||
Curl_uint_bset_remove(&multi->dirty, mid);
|
||||
Curl_uint_bset_remove(&multi->pending, mid);
|
||||
Curl_uint_bset_remove(&multi->msgsent, mid);
|
||||
DEBUGASSERT(Curl_uint32_tbl_contains(&multi->xfers, mid));
|
||||
Curl_uint32_tbl_remove(&multi->xfers, mid);
|
||||
Curl_uint32_bset_remove(&multi->process, mid);
|
||||
Curl_uint32_bset_remove(&multi->dirty, mid);
|
||||
Curl_uint32_bset_remove(&multi->pending, mid);
|
||||
Curl_uint32_bset_remove(&multi->msgsent, mid);
|
||||
data->multi = NULL;
|
||||
data->mid = UINT_MAX;
|
||||
data->master_mid = UINT_MAX;
|
||||
data->mid = UINT32_MAX;
|
||||
data->master_mid = UINT32_MAX;
|
||||
|
||||
/* NOTE NOTE NOTE
|
||||
We do not touch the easy handle here! */
|
||||
@@ -875,7 +875,7 @@ CURLMcode curl_multi_remove_handle(CURLM *m, CURL *d)
|
||||
|
||||
CURL_TRC_M(data, "removed from multi, mid=%u, running=%u, total=%u",
|
||||
mid, Curl_multi_xfers_running(multi),
|
||||
Curl_uint_tbl_count(&multi->xfers));
|
||||
Curl_uint32_tbl_count(&multi->xfers));
|
||||
return CURLM_OK;
|
||||
}
|
||||
|
||||
@@ -895,8 +895,8 @@ void Curl_detach_connection(struct Curl_easy *data)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
if(conn) {
|
||||
Curl_uint_spbset_remove(&conn->xfers_attached, data->mid);
|
||||
if(Curl_uint_spbset_empty(&conn->xfers_attached))
|
||||
Curl_uint32_spbset_remove(&conn->xfers_attached, data->mid);
|
||||
if(Curl_uint32_spbset_empty(&conn->xfers_attached))
|
||||
conn->attached_multi = NULL;
|
||||
}
|
||||
data->conn = NULL;
|
||||
@@ -914,7 +914,7 @@ void Curl_attach_connection(struct Curl_easy *data,
|
||||
DEBUGASSERT(!data->conn);
|
||||
DEBUGASSERT(conn);
|
||||
data->conn = conn;
|
||||
Curl_uint_spbset_add(&conn->xfers_attached, data->mid);
|
||||
Curl_uint32_spbset_add(&conn->xfers_attached, data->mid);
|
||||
/* all attached transfers must be from the same multi */
|
||||
if(!conn->attached_multi)
|
||||
conn->attached_multi = data->multi;
|
||||
@@ -1219,7 +1219,7 @@ CURLMcode curl_multi_fdset(CURLM *m,
|
||||
return CURLM_RECURSIVE_API_CALL;
|
||||
|
||||
Curl_pollset_init(&ps);
|
||||
if(Curl_uint_bset_first(&multi->process, &mid)) {
|
||||
if(Curl_uint32_bset_first(&multi->process, &mid)) {
|
||||
do {
|
||||
struct Curl_easy *data = Curl_multi_get_easy(multi, mid);
|
||||
|
||||
@@ -1248,7 +1248,7 @@ CURLMcode curl_multi_fdset(CURLM *m,
|
||||
this_max_fd = (int)ps.sockets[i];
|
||||
}
|
||||
}
|
||||
while(Curl_uint_bset_next(&multi->process, mid, &mid));
|
||||
while(Curl_uint32_bset_next(&multi->process, mid, &mid));
|
||||
}
|
||||
|
||||
Curl_cshutdn_setfds(&multi->cshutdn, multi->admin,
|
||||
@@ -1282,19 +1282,19 @@ CURLMcode curl_multi_waitfds(CURLM *m,
|
||||
|
||||
Curl_pollset_init(&ps);
|
||||
Curl_waitfds_init(&cwfds, ufds, size);
|
||||
if(Curl_uint_bset_first(&multi->process, &mid)) {
|
||||
if(Curl_uint32_bset_first(&multi->process, &mid)) {
|
||||
do {
|
||||
struct Curl_easy *data = Curl_multi_get_easy(multi, mid);
|
||||
if(!data) {
|
||||
DEBUGASSERT(0);
|
||||
Curl_uint_bset_remove(&multi->process, mid);
|
||||
Curl_uint_bset_remove(&multi->dirty, mid);
|
||||
Curl_uint32_bset_remove(&multi->process, mid);
|
||||
Curl_uint32_bset_remove(&multi->dirty, mid);
|
||||
continue;
|
||||
}
|
||||
Curl_multi_pollset(data, &ps);
|
||||
need += Curl_waitfds_add_ps(&cwfds, &ps);
|
||||
}
|
||||
while(Curl_uint_bset_next(&multi->process, mid, &mid));
|
||||
while(Curl_uint32_bset_next(&multi->process, mid, &mid));
|
||||
}
|
||||
|
||||
need += Curl_cshutdn_add_waitfds(&multi->cshutdn, multi->admin, &cwfds);
|
||||
@@ -1345,7 +1345,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
|
||||
unsigned int curl_nfds = 0; /* how many pfds are for curl transfers */
|
||||
struct Curl_easy *data = NULL;
|
||||
CURLMcode result = CURLM_OK;
|
||||
unsigned int mid;
|
||||
uint32_t mid;
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
WSANETWORKEVENTS wsa_events;
|
||||
@@ -1368,13 +1368,13 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
|
||||
Curl_pollfds_init(&cpfds, a_few_on_stack, NUM_POLLS_ON_STACK);
|
||||
|
||||
/* Add the curl handles to our pollfds first */
|
||||
if(Curl_uint_bset_first(&multi->process, &mid)) {
|
||||
if(Curl_uint32_bset_first(&multi->process, &mid)) {
|
||||
do {
|
||||
data = Curl_multi_get_easy(multi, mid);
|
||||
if(!data) {
|
||||
DEBUGASSERT(0);
|
||||
Curl_uint_bset_remove(&multi->process, mid);
|
||||
Curl_uint_bset_remove(&multi->dirty, mid);
|
||||
Curl_uint32_bset_remove(&multi->process, mid);
|
||||
Curl_uint32_bset_remove(&multi->dirty, mid);
|
||||
continue;
|
||||
}
|
||||
Curl_multi_pollset(data, &ps);
|
||||
@@ -1383,7 +1383,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
while(Curl_uint_bset_next(&multi->process, mid, &mid));
|
||||
while(Curl_uint32_bset_next(&multi->process, mid, &mid));
|
||||
}
|
||||
|
||||
if(Curl_cshutdn_add_pollfds(&multi->cshutdn, multi->admin, &cpfds)) {
|
||||
@@ -2330,9 +2330,9 @@ static CURLMcode state_connect(struct Curl_multi *multi,
|
||||
wait for an available connection. */
|
||||
multistate(data, MSTATE_PENDING);
|
||||
/* move from process to pending set */
|
||||
Curl_uint_bset_remove(&multi->process, data->mid);
|
||||
Curl_uint_bset_remove(&multi->dirty, data->mid);
|
||||
Curl_uint_bset_add(&multi->pending, data->mid);
|
||||
Curl_uint32_bset_remove(&multi->process, data->mid);
|
||||
Curl_uint32_bset_remove(&multi->dirty, data->mid);
|
||||
Curl_uint32_bset_add(&multi->pending, data->mid);
|
||||
*resultp = CURLE_OK;
|
||||
return rc;
|
||||
}
|
||||
@@ -2395,7 +2395,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
|
||||
/* transfer runs now, clear the dirty bit. This may be set
|
||||
* again during processing, triggering a re-run later. */
|
||||
Curl_uint_bset_remove(&multi->dirty, data->mid);
|
||||
Curl_uint32_bset_remove(&multi->dirty, data->mid);
|
||||
|
||||
if(data == multi->admin) {
|
||||
Curl_cshutdn_perform(&multi->cshutdn, multi->admin, CURL_SOCKET_TIMEOUT);
|
||||
@@ -2742,7 +2742,7 @@ statemachine_end:
|
||||
}
|
||||
|
||||
if(MSTATE_COMPLETED == data->mstate) {
|
||||
if(data->master_mid != UINT_MAX) {
|
||||
if(data->master_mid != UINT32_MAX) {
|
||||
/* A sub transfer, not for msgsent to application */
|
||||
struct Curl_easy *mdata;
|
||||
|
||||
@@ -2773,10 +2773,10 @@ statemachine_end:
|
||||
multistate(data, MSTATE_MSGSENT);
|
||||
|
||||
/* remove from the other sets, add to msgsent */
|
||||
Curl_uint_bset_remove(&multi->process, data->mid);
|
||||
Curl_uint_bset_remove(&multi->dirty, data->mid);
|
||||
Curl_uint_bset_remove(&multi->pending, data->mid);
|
||||
Curl_uint_bset_add(&multi->msgsent, data->mid);
|
||||
Curl_uint32_bset_remove(&multi->process, data->mid);
|
||||
Curl_uint32_bset_remove(&multi->dirty, data->mid);
|
||||
Curl_uint32_bset_remove(&multi->pending, data->mid);
|
||||
Curl_uint32_bset_add(&multi->msgsent, data->mid);
|
||||
--multi->xfers_alive;
|
||||
return CURLM_OK;
|
||||
}
|
||||
@@ -2793,7 +2793,7 @@ CURLMcode curl_multi_perform(CURLM *m, int *running_handles)
|
||||
struct Curl_tree *t = NULL;
|
||||
struct curltime now = curlx_now();
|
||||
struct Curl_multi *multi = m;
|
||||
unsigned int mid;
|
||||
uint32_t mid;
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
@@ -2806,7 +2806,7 @@ CURLMcode curl_multi_perform(CURLM *m, int *running_handles)
|
||||
return CURLM_RECURSIVE_API_CALL;
|
||||
|
||||
sigpipe_init(&pipe_st);
|
||||
if(Curl_uint_bset_first(&multi->process, &mid)) {
|
||||
if(Curl_uint32_bset_first(&multi->process, &mid)) {
|
||||
CURL_TRC_M(multi->admin, "multi_perform(running=%u)",
|
||||
Curl_multi_xfers_running(multi));
|
||||
do {
|
||||
@@ -2814,8 +2814,8 @@ CURLMcode curl_multi_perform(CURLM *m, int *running_handles)
|
||||
CURLMcode result;
|
||||
if(!data) {
|
||||
DEBUGASSERT(0);
|
||||
Curl_uint_bset_remove(&multi->process, mid);
|
||||
Curl_uint_bset_remove(&multi->dirty, mid);
|
||||
Curl_uint32_bset_remove(&multi->process, mid);
|
||||
Curl_uint32_bset_remove(&multi->dirty, mid);
|
||||
continue;
|
||||
}
|
||||
sigpipe_apply(data, &pipe_st);
|
||||
@@ -2823,7 +2823,7 @@ CURLMcode curl_multi_perform(CURLM *m, int *running_handles)
|
||||
if(result)
|
||||
returncode = result;
|
||||
}
|
||||
while(Curl_uint_bset_next(&multi->process, mid, &mid));
|
||||
while(Curl_uint32_bset_next(&multi->process, mid, &mid));
|
||||
}
|
||||
sigpipe_restore(&pipe_st);
|
||||
|
||||
@@ -2876,7 +2876,7 @@ CURLMcode curl_multi_cleanup(CURLM *m)
|
||||
struct Curl_multi *multi = m;
|
||||
if(GOOD_MULTI_HANDLE(multi)) {
|
||||
void *entry;
|
||||
unsigned int mid;
|
||||
uint32_t mid;
|
||||
if(multi->in_callback)
|
||||
return CURLM_RECURSIVE_API_CALL;
|
||||
if(multi->in_ntfy_callback)
|
||||
@@ -2884,7 +2884,7 @@ CURLMcode curl_multi_cleanup(CURLM *m)
|
||||
|
||||
/* First remove all remaining easy handles,
|
||||
* close internal ones. admin handle is special */
|
||||
if(Curl_uint_tbl_first(&multi->xfers, &mid, &entry)) {
|
||||
if(Curl_uint32_tbl_first(&multi->xfers, &mid, &entry)) {
|
||||
do {
|
||||
struct Curl_easy *data = entry;
|
||||
if(!GOOD_EASY_HANDLE(data))
|
||||
@@ -2906,8 +2906,8 @@ CURLMcode curl_multi_cleanup(CURLM *m)
|
||||
(void)multi_done(data, CURLE_OK, TRUE);
|
||||
|
||||
data->multi = NULL; /* clear the association */
|
||||
Curl_uint_tbl_remove(&multi->xfers, mid);
|
||||
data->mid = UINT_MAX;
|
||||
Curl_uint32_tbl_remove(&multi->xfers, mid);
|
||||
data->mid = UINT32_MAX;
|
||||
|
||||
#ifdef USE_LIBPSL
|
||||
if(data->psl == &multi->psl)
|
||||
@@ -2916,7 +2916,7 @@ CURLMcode curl_multi_cleanup(CURLM *m)
|
||||
if(data->state.internal)
|
||||
Curl_close(&data);
|
||||
}
|
||||
while(Curl_uint_tbl_next(&multi->xfers, mid, &mid, &entry));
|
||||
while(Curl_uint32_tbl_next(&multi->xfers, mid, &mid, &entry));
|
||||
}
|
||||
|
||||
Curl_cpool_destroy(&multi->cpool);
|
||||
@@ -2924,7 +2924,7 @@ CURLMcode curl_multi_cleanup(CURLM *m)
|
||||
if(multi->admin) {
|
||||
CURL_TRC_M(multi->admin, "multi_cleanup, closing admin handle, done");
|
||||
multi->admin->multi = NULL;
|
||||
Curl_uint_tbl_remove(&multi->xfers, multi->admin->mid);
|
||||
Curl_uint32_tbl_remove(&multi->xfers, multi->admin->mid);
|
||||
Curl_close(&multi->admin);
|
||||
}
|
||||
|
||||
@@ -2952,16 +2952,16 @@ CURLMcode curl_multi_cleanup(CURLM *m)
|
||||
multi_xfer_bufs_free(multi);
|
||||
Curl_mntfy_cleanup(multi);
|
||||
#ifdef DEBUGBUILD
|
||||
if(Curl_uint_tbl_count(&multi->xfers)) {
|
||||
if(Curl_uint32_tbl_count(&multi->xfers)) {
|
||||
multi_xfer_tbl_dump(multi);
|
||||
DEBUGASSERT(0);
|
||||
}
|
||||
#endif
|
||||
Curl_uint_bset_destroy(&multi->process);
|
||||
Curl_uint_bset_destroy(&multi->dirty);
|
||||
Curl_uint_bset_destroy(&multi->pending);
|
||||
Curl_uint_bset_destroy(&multi->msgsent);
|
||||
Curl_uint_tbl_destroy(&multi->xfers);
|
||||
Curl_uint32_bset_destroy(&multi->process);
|
||||
Curl_uint32_bset_destroy(&multi->dirty);
|
||||
Curl_uint32_bset_destroy(&multi->pending);
|
||||
Curl_uint32_bset_destroy(&multi->msgsent);
|
||||
Curl_uint32_tbl_destroy(&multi->xfers);
|
||||
free(multi);
|
||||
|
||||
return CURLM_OK;
|
||||
@@ -3120,17 +3120,17 @@ static CURLMcode multi_run_dirty(struct multi_run_ctx *mrc)
|
||||
{
|
||||
struct Curl_multi *multi = mrc->multi;
|
||||
CURLMcode result = CURLM_OK;
|
||||
unsigned int mid;
|
||||
uint32_t mid;
|
||||
|
||||
if(Curl_uint_bset_first(&multi->dirty, &mid)) {
|
||||
if(Curl_uint32_bset_first(&multi->dirty, &mid)) {
|
||||
do {
|
||||
struct Curl_easy *data = Curl_multi_get_easy(multi, mid);
|
||||
if(data) {
|
||||
CURL_TRC_M(data, "multi_run_dirty");
|
||||
|
||||
if(!Curl_uint_bset_contains(&multi->process, mid)) {
|
||||
if(!Curl_uint32_bset_contains(&multi->process, mid)) {
|
||||
/* We are no longer processing this transfer */
|
||||
Curl_uint_bset_remove(&multi->dirty, mid);
|
||||
Curl_uint32_bset_remove(&multi->dirty, mid);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3148,10 +3148,10 @@ static CURLMcode multi_run_dirty(struct multi_run_ctx *mrc)
|
||||
}
|
||||
else {
|
||||
CURL_TRC_M(multi->admin, "multi_run_dirty, %u no longer found", mid);
|
||||
Curl_uint_bset_remove(&multi->dirty, mid);
|
||||
Curl_uint32_bset_remove(&multi->dirty, mid);
|
||||
}
|
||||
}
|
||||
while(Curl_uint_bset_next(&multi->dirty, mid, &mid));
|
||||
while(Curl_uint32_bset_next(&multi->dirty, mid, &mid));
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -3364,22 +3364,22 @@ CURLMcode curl_multi_socket_all(CURLM *m, int *running_handles)
|
||||
|
||||
static bool multi_has_dirties(struct Curl_multi *multi)
|
||||
{
|
||||
unsigned int mid;
|
||||
if(Curl_uint_bset_first(&multi->dirty, &mid)) {
|
||||
uint32_t mid;
|
||||
if(Curl_uint32_bset_first(&multi->dirty, &mid)) {
|
||||
do {
|
||||
struct Curl_easy *data = Curl_multi_get_easy(multi, mid);
|
||||
if(data) {
|
||||
if(Curl_uint_bset_contains(&multi->process, mid))
|
||||
if(Curl_uint32_bset_contains(&multi->process, mid))
|
||||
return TRUE;
|
||||
/* We are no longer processing this transfer */
|
||||
Curl_uint_bset_remove(&multi->dirty, mid);
|
||||
Curl_uint32_bset_remove(&multi->dirty, mid);
|
||||
}
|
||||
else {
|
||||
CURL_TRC_M(multi->admin, "dirty transfer %u no longer found", mid);
|
||||
Curl_uint_bset_remove(&multi->dirty, mid);
|
||||
Curl_uint32_bset_remove(&multi->dirty, mid);
|
||||
}
|
||||
}
|
||||
while(Curl_uint_bset_next(&multi->dirty, mid, &mid));
|
||||
while(Curl_uint32_bset_next(&multi->dirty, mid, &mid));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -3739,8 +3739,8 @@ static void move_pending_to_connect(struct Curl_multi *multi,
|
||||
DEBUGASSERT(data->mstate == MSTATE_PENDING);
|
||||
|
||||
/* Remove this node from the pending set, add into process set */
|
||||
Curl_uint_bset_remove(&multi->pending, data->mid);
|
||||
Curl_uint_bset_add(&multi->process, data->mid);
|
||||
Curl_uint32_bset_remove(&multi->pending, data->mid);
|
||||
Curl_uint32_bset_add(&multi->process, data->mid);
|
||||
|
||||
multistate(data, MSTATE_CONNECT);
|
||||
Curl_multi_mark_dirty(data); /* make it run */
|
||||
@@ -3762,8 +3762,8 @@ static void move_pending_to_connect(struct Curl_multi *multi,
|
||||
*/
|
||||
static void process_pending_handles(struct Curl_multi *multi)
|
||||
{
|
||||
unsigned int mid;
|
||||
if(Curl_uint_bset_first(&multi->pending, &mid)) {
|
||||
uint32_t mid;
|
||||
if(Curl_uint32_bset_first(&multi->pending, &mid)) {
|
||||
do {
|
||||
struct Curl_easy *data = Curl_multi_get_easy(multi, mid);
|
||||
if(data) {
|
||||
@@ -3771,10 +3771,10 @@ static void process_pending_handles(struct Curl_multi *multi)
|
||||
break;
|
||||
}
|
||||
/* transfer no longer known, should not happen */
|
||||
Curl_uint_bset_remove(&multi->pending, mid);
|
||||
Curl_uint32_bset_remove(&multi->pending, mid);
|
||||
DEBUGASSERT(0);
|
||||
}
|
||||
while(Curl_uint_bset_next(&multi->pending, mid, &mid));
|
||||
while(Curl_uint32_bset_next(&multi->pending, mid, &mid));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3799,19 +3799,19 @@ CURL **curl_multi_get_handles(CURLM *m)
|
||||
{
|
||||
struct Curl_multi *multi = m;
|
||||
void *entry;
|
||||
unsigned int count = Curl_uint_tbl_count(&multi->xfers);
|
||||
unsigned int count = Curl_uint32_tbl_count(&multi->xfers);
|
||||
CURL **a = malloc(sizeof(struct Curl_easy *) * (count + 1));
|
||||
if(a) {
|
||||
unsigned int i = 0, mid;
|
||||
|
||||
if(Curl_uint_tbl_first(&multi->xfers, &mid, &entry)) {
|
||||
if(Curl_uint32_tbl_first(&multi->xfers, &mid, &entry)) {
|
||||
do {
|
||||
struct Curl_easy *data = entry;
|
||||
DEBUGASSERT(i < count);
|
||||
if(!data->state.internal)
|
||||
a[i++] = data;
|
||||
}
|
||||
while(Curl_uint_tbl_next(&multi->xfers, mid, &mid, &entry));
|
||||
while(Curl_uint32_tbl_next(&multi->xfers, mid, &mid, &entry));
|
||||
}
|
||||
a[i] = NULL; /* last entry is a NULL */
|
||||
}
|
||||
@@ -3823,7 +3823,7 @@ CURLMcode curl_multi_get_offt(CURLM *m,
|
||||
curl_off_t *pvalue)
|
||||
{
|
||||
struct Curl_multi *multi = m;
|
||||
unsigned int n;
|
||||
uint32_t n;
|
||||
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
return CURLM_BAD_HANDLE;
|
||||
@@ -3832,22 +3832,22 @@ CURLMcode curl_multi_get_offt(CURLM *m,
|
||||
|
||||
switch(info) {
|
||||
case CURLMINFO_XFERS_CURRENT:
|
||||
n = Curl_uint_tbl_count(&multi->xfers);
|
||||
n = Curl_uint32_tbl_count(&multi->xfers);
|
||||
if(n && multi->admin)
|
||||
--n;
|
||||
*pvalue = (curl_off_t)n;
|
||||
return CURLM_OK;
|
||||
case CURLMINFO_XFERS_RUNNING:
|
||||
n = Curl_uint_bset_count(&multi->process);
|
||||
if(n && Curl_uint_bset_contains(&multi->process, multi->admin->mid))
|
||||
n = Curl_uint32_bset_count(&multi->process);
|
||||
if(n && Curl_uint32_bset_contains(&multi->process, multi->admin->mid))
|
||||
--n;
|
||||
*pvalue = (curl_off_t)n;
|
||||
return CURLM_OK;
|
||||
case CURLMINFO_XFERS_PENDING:
|
||||
*pvalue = (curl_off_t)Curl_uint_bset_count(&multi->pending);
|
||||
*pvalue = (curl_off_t)Curl_uint32_bset_count(&multi->pending);
|
||||
return CURLM_OK;
|
||||
case CURLMINFO_XFERS_DONE:
|
||||
*pvalue = (curl_off_t)Curl_uint_bset_count(&multi->msgsent);
|
||||
*pvalue = (curl_off_t)Curl_uint32_bset_count(&multi->msgsent);
|
||||
return CURLM_OK;
|
||||
case CURLMINFO_XFERS_ADDED:
|
||||
*pvalue = multi->xfers_total_ever;
|
||||
@@ -4025,14 +4025,14 @@ static void multi_xfer_bufs_free(struct Curl_multi *multi)
|
||||
}
|
||||
|
||||
struct Curl_easy *Curl_multi_get_easy(struct Curl_multi *multi,
|
||||
unsigned int mid)
|
||||
uint32_t mid)
|
||||
{
|
||||
struct Curl_easy *data = Curl_uint_tbl_get(&multi->xfers, mid);
|
||||
struct Curl_easy *data = Curl_uint32_tbl_get(&multi->xfers, mid);
|
||||
if(data && GOOD_EASY_HANDLE(data))
|
||||
return data;
|
||||
CURL_TRC_M(multi->admin, "invalid easy handle in xfer table for mid=%u",
|
||||
mid);
|
||||
Curl_uint_tbl_remove(&multi->xfers, mid);
|
||||
Curl_uint32_tbl_remove(&multi->xfers, mid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -4043,14 +4043,14 @@ unsigned int Curl_multi_xfers_running(struct Curl_multi *multi)
|
||||
|
||||
void Curl_multi_mark_dirty(struct Curl_easy *data)
|
||||
{
|
||||
if(data->multi && data->mid != UINT_MAX)
|
||||
Curl_uint_bset_add(&data->multi->dirty, data->mid);
|
||||
if(data->multi && data->mid != UINT32_MAX)
|
||||
Curl_uint32_bset_add(&data->multi->dirty, data->mid);
|
||||
}
|
||||
|
||||
void Curl_multi_clear_dirty(struct Curl_easy *data)
|
||||
{
|
||||
if(data->multi && data->mid != UINT_MAX)
|
||||
Curl_uint_bset_remove(&data->multi->dirty, data->mid);
|
||||
if(data->multi && data->mid != UINT32_MAX)
|
||||
Curl_uint32_bset_remove(&data->multi->dirty, data->mid);
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_notify_enable(CURLM *m, unsigned int notification)
|
||||
@@ -4072,7 +4072,7 @@ CURLMcode curl_multi_notify_disable(CURLM *m, unsigned int notification)
|
||||
}
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
static void multi_xfer_dump(struct Curl_multi *multi, unsigned int mid,
|
||||
static void multi_xfer_dump(struct Curl_multi *multi, uint32_t mid,
|
||||
void *entry)
|
||||
{
|
||||
struct Curl_easy *data = entry;
|
||||
@@ -4092,14 +4092,14 @@ static void multi_xfer_dump(struct Curl_multi *multi, unsigned int mid,
|
||||
|
||||
static void multi_xfer_tbl_dump(struct Curl_multi *multi)
|
||||
{
|
||||
unsigned int mid;
|
||||
uint32_t mid;
|
||||
void *entry;
|
||||
curl_mfprintf(stderr, "=== multi xfer table (count=%u, capacity=%u\n",
|
||||
Curl_uint_tbl_count(&multi->xfers),
|
||||
Curl_uint_tbl_capacity(&multi->xfers));
|
||||
if(Curl_uint_tbl_first(&multi->xfers, &mid, &entry)) {
|
||||
Curl_uint32_tbl_count(&multi->xfers),
|
||||
Curl_uint32_tbl_capacity(&multi->xfers));
|
||||
if(Curl_uint32_tbl_first(&multi->xfers, &mid, &entry)) {
|
||||
multi_xfer_dump(multi, mid, entry);
|
||||
while(Curl_uint_tbl_next(&multi->xfers, mid, &mid, &entry))
|
||||
while(Curl_uint32_tbl_next(&multi->xfers, mid, &mid, &entry))
|
||||
multi_xfer_dump(multi, mid, entry);
|
||||
}
|
||||
curl_mfprintf(stderr, "===\n");
|
||||
|
||||
@@ -55,7 +55,7 @@ static void mev_in_callback(struct Curl_multi *multi, bool value)
|
||||
* what to supervise (CURL_POLL_IN/CURL_POLL_OUT/CURL_POLL_REMOVE)
|
||||
*/
|
||||
struct mev_sh_entry {
|
||||
struct uint_spbset xfers; /* bitset of transfers `mid`s on this socket */
|
||||
struct uint32_spbset xfers; /* bitset of transfers `mid`s on this socket */
|
||||
struct connectdata *conn; /* connection using this socket or NULL */
|
||||
void *user_data; /* libcurl app data via curl_multi_assign() */
|
||||
unsigned int action; /* CURL_POLL_IN/CURL_POLL_OUT we last told the
|
||||
@@ -84,7 +84,7 @@ static size_t mev_sh_entry_compare(void *k1, size_t k1_len,
|
||||
static void mev_sh_entry_dtor(void *freethis)
|
||||
{
|
||||
struct mev_sh_entry *entry = (struct mev_sh_entry *)freethis;
|
||||
Curl_uint_spbset_destroy(&entry->xfers);
|
||||
Curl_uint32_spbset_destroy(&entry->xfers);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ mev_sh_entry_add(struct Curl_hash *sh, curl_socket_t s)
|
||||
if(!check)
|
||||
return NULL; /* major failure */
|
||||
|
||||
Curl_uint_spbset_init(&check->xfers);
|
||||
Curl_uint32_spbset_init(&check->xfers);
|
||||
|
||||
/* make/add new hash entry */
|
||||
if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
|
||||
@@ -135,13 +135,13 @@ static void mev_sh_entry_kill(struct Curl_multi *multi, curl_socket_t s)
|
||||
|
||||
static size_t mev_sh_entry_user_count(struct mev_sh_entry *e)
|
||||
{
|
||||
return Curl_uint_spbset_count(&e->xfers) + (e->conn ? 1 : 0);
|
||||
return Curl_uint32_spbset_count(&e->xfers) + (e->conn ? 1 : 0);
|
||||
}
|
||||
|
||||
static bool mev_sh_entry_xfer_known(struct mev_sh_entry *e,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
return Curl_uint_spbset_contains(&e->xfers, data->mid);
|
||||
return Curl_uint32_spbset_contains(&e->xfers, data->mid);
|
||||
}
|
||||
|
||||
static bool mev_sh_entry_conn_known(struct mev_sh_entry *e,
|
||||
@@ -155,7 +155,7 @@ static bool mev_sh_entry_xfer_add(struct mev_sh_entry *e,
|
||||
{
|
||||
/* detect weird values */
|
||||
DEBUGASSERT(mev_sh_entry_user_count(e) < 100000);
|
||||
return Curl_uint_spbset_add(&e->xfers, data->mid);
|
||||
return Curl_uint32_spbset_add(&e->xfers, data->mid);
|
||||
}
|
||||
|
||||
static bool mev_sh_entry_conn_add(struct mev_sh_entry *e,
|
||||
@@ -174,9 +174,9 @@ static bool mev_sh_entry_conn_add(struct mev_sh_entry *e,
|
||||
static bool mev_sh_entry_xfer_remove(struct mev_sh_entry *e,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
bool present = Curl_uint_spbset_contains(&e->xfers, data->mid);
|
||||
bool present = Curl_uint32_spbset_contains(&e->xfers, data->mid);
|
||||
if(present)
|
||||
Curl_uint_spbset_remove(&e->xfers, data->mid);
|
||||
Curl_uint32_spbset_remove(&e->xfers, data->mid);
|
||||
return present;
|
||||
}
|
||||
|
||||
@@ -356,7 +356,7 @@ static CURLMcode mev_pollset_diff(struct Curl_multi *multi,
|
||||
", total=%u/%d (xfer/conn)", s,
|
||||
conn ? "connection" : "transfer",
|
||||
conn ? conn->connection_id : data->mid,
|
||||
Curl_uint_spbset_count(&entry->xfers),
|
||||
Curl_uint32_spbset_count(&entry->xfers),
|
||||
entry->conn ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
@@ -424,7 +424,7 @@ static CURLMcode mev_pollset_diff(struct Curl_multi *multi,
|
||||
return mresult;
|
||||
CURL_TRC_M(data, "ev entry fd=%" FMT_SOCKET_T ", removed transfer, "
|
||||
"total=%u/%d (xfer/conn)", s,
|
||||
Curl_uint_spbset_count(&entry->xfers),
|
||||
Curl_uint32_spbset_count(&entry->xfers),
|
||||
entry->conn ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
@@ -545,18 +545,18 @@ CURLMcode Curl_multi_ev_assess_conn(struct Curl_multi *multi,
|
||||
}
|
||||
|
||||
CURLMcode Curl_multi_ev_assess_xfer_bset(struct Curl_multi *multi,
|
||||
struct uint_bset *set)
|
||||
struct uint32_bset *set)
|
||||
{
|
||||
unsigned int mid;
|
||||
uint32_t mid;
|
||||
CURLMcode result = CURLM_OK;
|
||||
|
||||
if(multi && multi->socket_cb && Curl_uint_bset_first(set, &mid)) {
|
||||
if(multi && multi->socket_cb && Curl_uint32_bset_first(set, &mid)) {
|
||||
do {
|
||||
struct Curl_easy *data = Curl_multi_get_easy(multi, mid);
|
||||
if(data)
|
||||
result = Curl_multi_ev_assess_xfer(multi, data);
|
||||
}
|
||||
while(!result && Curl_uint_bset_next(set, mid, &mid));
|
||||
while(!result && Curl_uint32_bset_next(set, mid, &mid));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -588,9 +588,9 @@ void Curl_multi_ev_dirty_xfers(struct Curl_multi *multi,
|
||||
and just move on. */
|
||||
if(entry) {
|
||||
struct Curl_easy *data;
|
||||
unsigned int mid;
|
||||
uint32_t mid;
|
||||
|
||||
if(Curl_uint_spbset_first(&entry->xfers, &mid)) {
|
||||
if(Curl_uint32_spbset_first(&entry->xfers, &mid)) {
|
||||
do {
|
||||
data = Curl_multi_get_easy(multi, mid);
|
||||
if(data) {
|
||||
@@ -598,10 +598,10 @@ void Curl_multi_ev_dirty_xfers(struct Curl_multi *multi,
|
||||
}
|
||||
else {
|
||||
CURL_TRC_M(multi->admin, "socket transfer %u no longer found", mid);
|
||||
Curl_uint_spbset_remove(&entry->xfers, mid);
|
||||
Curl_uint32_spbset_remove(&entry->xfers, mid);
|
||||
}
|
||||
}
|
||||
while(Curl_uint_spbset_next(&entry->xfers, mid, &mid));
|
||||
while(Curl_uint32_spbset_next(&entry->xfers, mid, &mid));
|
||||
}
|
||||
|
||||
if(entry->conn)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
struct Curl_easy;
|
||||
struct Curl_multi;
|
||||
struct easy_pollset;
|
||||
struct uint_bset;
|
||||
struct uint32_bset;
|
||||
|
||||
/* meta key for event pollset at easy handle or connection */
|
||||
#define CURL_META_MEV_POLLSET "meta:mev:ps"
|
||||
@@ -55,7 +55,7 @@ CURLMcode Curl_multi_ev_assess_xfer(struct Curl_multi *multi,
|
||||
struct Curl_easy *data);
|
||||
/* Assess all easy handles on the list */
|
||||
CURLMcode Curl_multi_ev_assess_xfer_bset(struct Curl_multi *multi,
|
||||
struct uint_bset *set);
|
||||
struct uint32_bset *set);
|
||||
/* Assess the connection by getting its current pollset */
|
||||
CURLMcode Curl_multi_ev_assess_conn(struct Curl_multi *multi,
|
||||
struct Curl_easy *data,
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
|
||||
|
||||
struct mntfy_entry {
|
||||
unsigned int mid;
|
||||
unsigned int type;
|
||||
uint32_t mid;
|
||||
uint32_t type;
|
||||
};
|
||||
|
||||
#define CURL_MNTFY_CHUNK_SIZE 128
|
||||
@@ -69,7 +69,7 @@ static void mnfty_chunk_reset(struct mntfy_chunk *chunk)
|
||||
|
||||
static bool mntfy_chunk_append(struct mntfy_chunk *chunk,
|
||||
struct Curl_easy *data,
|
||||
unsigned int type)
|
||||
uint32_t type)
|
||||
{
|
||||
struct mntfy_entry *e;
|
||||
|
||||
@@ -116,7 +116,7 @@ static void mntfy_chunk_dispatch_all(struct Curl_multi *multi,
|
||||
e = &chunk->entries[chunk->r_offset];
|
||||
data = e->mid ? Curl_multi_get_easy(multi, e->mid) : multi->admin;
|
||||
/* only when notification has not been disabled in the meantime */
|
||||
if(data && Curl_uint_bset_contains(&multi->ntfy.enabled, e->type)) {
|
||||
if(data && Curl_uint32_bset_contains(&multi->ntfy.enabled, e->type)) {
|
||||
/* this may cause new notifications to be added! */
|
||||
CURL_TRC_M(multi->admin, "[NTFY] dispatch %d to xfer %u",
|
||||
e->type, e->mid);
|
||||
@@ -132,12 +132,12 @@ static void mntfy_chunk_dispatch_all(struct Curl_multi *multi,
|
||||
void Curl_mntfy_init(struct Curl_multi *multi)
|
||||
{
|
||||
memset(&multi->ntfy, 0, sizeof(multi->ntfy));
|
||||
Curl_uint_bset_init(&multi->ntfy.enabled);
|
||||
Curl_uint32_bset_init(&multi->ntfy.enabled);
|
||||
}
|
||||
|
||||
CURLMcode Curl_mntfy_resize(struct Curl_multi *multi)
|
||||
{
|
||||
if(Curl_uint_bset_resize(&multi->ntfy.enabled, CURLMNOTIFY_EASY_DONE + 1))
|
||||
if(Curl_uint32_bset_resize(&multi->ntfy.enabled, CURLMNOTIFY_EASY_DONE + 1))
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
return CURLM_OK;
|
||||
}
|
||||
@@ -150,14 +150,14 @@ void Curl_mntfy_cleanup(struct Curl_multi *multi)
|
||||
mnfty_chunk_destroy(chunk);
|
||||
}
|
||||
multi->ntfy.tail = NULL;
|
||||
Curl_uint_bset_destroy(&multi->ntfy.enabled);
|
||||
Curl_uint32_bset_destroy(&multi->ntfy.enabled);
|
||||
}
|
||||
|
||||
CURLMcode Curl_mntfy_enable(struct Curl_multi *multi, unsigned int type)
|
||||
{
|
||||
if(type > CURLMNOTIFY_EASY_DONE)
|
||||
return CURLM_UNKNOWN_OPTION;
|
||||
Curl_uint_bset_add(&multi->ntfy.enabled, type);
|
||||
Curl_uint32_bset_add(&multi->ntfy.enabled, type);
|
||||
return CURLM_OK;
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ CURLMcode Curl_mntfy_disable(struct Curl_multi *multi, unsigned int type)
|
||||
{
|
||||
if(type > CURLMNOTIFY_EASY_DONE)
|
||||
return CURLM_UNKNOWN_OPTION;
|
||||
Curl_uint_bset_remove(&multi->ntfy.enabled, type);
|
||||
Curl_uint32_bset_remove(&multi->ntfy.enabled, (uint32_t)type);
|
||||
return CURLM_OK;
|
||||
}
|
||||
|
||||
@@ -173,12 +173,12 @@ void Curl_mntfy_add(struct Curl_easy *data, unsigned int type)
|
||||
{
|
||||
struct Curl_multi *multi = data ? data->multi : NULL;
|
||||
if(multi && multi->ntfy.ntfy_cb && !multi->ntfy.failure &&
|
||||
Curl_uint_bset_contains(&multi->ntfy.enabled, type)) {
|
||||
Curl_uint32_bset_contains(&multi->ntfy.enabled, (uint32_t)type)) {
|
||||
/* append to list of outstanding notifications */
|
||||
struct mntfy_chunk *tail = mntfy_non_full_tail(&multi->ntfy);
|
||||
CURL_TRC_M(data, "[NTFY] add %d for xfer %u", type, data->mid);
|
||||
if(tail)
|
||||
mntfy_chunk_append(tail, data, type);
|
||||
mntfy_chunk_append(tail, data, (uint32_t)type);
|
||||
else
|
||||
multi->ntfy.failure = CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ struct Curl_multi;
|
||||
struct curl_multi_ntfy {
|
||||
curl_notify_callback ntfy_cb;
|
||||
void *ntfy_cb_data;
|
||||
struct uint_bset enabled;
|
||||
struct uint32_bset enabled;
|
||||
CURLMcode failure;
|
||||
struct mntfy_chunk *head;
|
||||
struct mntfy_chunk *tail;
|
||||
|
||||
@@ -91,12 +91,12 @@ struct Curl_multi {
|
||||
unsigned int xfers_alive; /* amount of added transfers that have
|
||||
not yet reached COMPLETE state */
|
||||
curl_off_t xfers_total_ever; /* total of added transfers, ever. */
|
||||
struct uint_tbl xfers; /* transfers added to this multi */
|
||||
struct uint32_tbl xfers; /* transfers added to this multi */
|
||||
/* Each transfer's mid may be present in at most one of these */
|
||||
struct uint_bset process; /* transfer being processed */
|
||||
struct uint_bset dirty; /* transfer to be run NOW, e.g. ASAP. */
|
||||
struct uint_bset pending; /* transfers in waiting (conn limit etc.) */
|
||||
struct uint_bset msgsent; /* transfers done with message for application */
|
||||
struct uint32_bset process; /* transfer being processed */
|
||||
struct uint32_bset dirty; /* transfer to be run NOW, e.g. ASAP. */
|
||||
struct uint32_bset pending; /* transfers in waiting (conn limit etc.) */
|
||||
struct uint32_bset msgsent; /* transfers done with message for application */
|
||||
|
||||
struct Curl_llist msglist; /* a list of messages from completed transfers */
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ void Curl_multi_xfer_sockbuf_release(struct Curl_easy *data, char *buf);
|
||||
* Returns NULL if not found.
|
||||
*/
|
||||
struct Curl_easy *Curl_multi_get_easy(struct Curl_multi *multi,
|
||||
unsigned int mid);
|
||||
uint32_t mid);
|
||||
|
||||
/* Get the # of transfers current in process/pending. */
|
||||
unsigned int Curl_multi_xfers_running(struct Curl_multi *multi);
|
||||
|
||||
102
lib/uint-bset.c
102
lib/uint-bset.c
@@ -30,32 +30,32 @@
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define CURL_UINT_BSET_MAGIC 0x62757473
|
||||
#define CURL_UINT32_BSET_MAGIC 0x62757473
|
||||
#endif
|
||||
|
||||
void Curl_uint_bset_init(struct uint_bset *bset)
|
||||
void Curl_uint32_bset_init(struct uint32_bset *bset)
|
||||
{
|
||||
memset(bset, 0, sizeof(*bset));
|
||||
#ifdef DEBUGBUILD
|
||||
bset->init = CURL_UINT_BSET_MAGIC;
|
||||
bset->init = CURL_UINT32_BSET_MAGIC;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
CURLcode Curl_uint_bset_resize(struct uint_bset *bset, unsigned int nmax)
|
||||
CURLcode Curl_uint32_bset_resize(struct uint32_bset *bset, uint32_t nmax)
|
||||
{
|
||||
unsigned int nslots = (nmax < (UINT_MAX-63)) ?
|
||||
((nmax + 63) / 64) : (UINT_MAX / 64);
|
||||
uint32_t nslots = (nmax < (UINT32_MAX-63)) ?
|
||||
((nmax + 63) / 64) : (UINT32_MAX / 64);
|
||||
|
||||
DEBUGASSERT(bset->init == CURL_UINT_BSET_MAGIC);
|
||||
DEBUGASSERT(bset->init == CURL_UINT32_BSET_MAGIC);
|
||||
if(nslots != bset->nslots) {
|
||||
curl_uint64_t *slots = calloc(nslots, sizeof(curl_uint64_t));
|
||||
uint64_t *slots = calloc(nslots, sizeof(uint64_t));
|
||||
if(!slots)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(bset->slots) {
|
||||
memcpy(slots, bset->slots,
|
||||
(CURLMIN(nslots, bset->nslots) * sizeof(curl_uint64_t)));
|
||||
(CURLMIN(nslots, bset->nslots) * sizeof(uint64_t)));
|
||||
free(bset->slots);
|
||||
}
|
||||
bset->slots = slots;
|
||||
@@ -66,24 +66,24 @@ CURLcode Curl_uint_bset_resize(struct uint_bset *bset, unsigned int nmax)
|
||||
}
|
||||
|
||||
|
||||
void Curl_uint_bset_destroy(struct uint_bset *bset)
|
||||
void Curl_uint32_bset_destroy(struct uint32_bset *bset)
|
||||
{
|
||||
DEBUGASSERT(bset->init == CURL_UINT_BSET_MAGIC);
|
||||
DEBUGASSERT(bset->init == CURL_UINT32_BSET_MAGIC);
|
||||
free(bset->slots);
|
||||
memset(bset, 0, sizeof(*bset));
|
||||
}
|
||||
|
||||
#ifdef UNITTESTS
|
||||
UNITTEST unsigned int Curl_uint_bset_capacity(struct uint_bset *bset)
|
||||
UNITTEST uint32_t Curl_uint32_bset_capacity(struct uint32_bset *bset)
|
||||
{
|
||||
return bset->nslots * 64;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int Curl_uint_bset_count(struct uint_bset *bset)
|
||||
uint32_t Curl_uint32_bset_count(struct uint32_bset *bset)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int n = 0;
|
||||
uint32_t i;
|
||||
uint32_t n = 0;
|
||||
for(i = 0; i < bset->nslots; ++i) {
|
||||
if(bset->slots[i])
|
||||
n += CURL_POPCOUNT64(bset->slots[i]);
|
||||
@@ -91,9 +91,9 @@ unsigned int Curl_uint_bset_count(struct uint_bset *bset)
|
||||
return n;
|
||||
}
|
||||
|
||||
bool Curl_uint_bset_empty(struct uint_bset *bset)
|
||||
bool Curl_uint32_bset_empty(struct uint32_bset *bset)
|
||||
{
|
||||
unsigned int i;
|
||||
uint32_t i;
|
||||
for(i = bset->first_slot_used; i < bset->nslots; ++i) {
|
||||
if(bset->slots[i])
|
||||
return FALSE;
|
||||
@@ -102,47 +102,47 @@ bool Curl_uint_bset_empty(struct uint_bset *bset)
|
||||
}
|
||||
|
||||
|
||||
void Curl_uint_bset_clear(struct uint_bset *bset)
|
||||
void Curl_uint32_bset_clear(struct uint32_bset *bset)
|
||||
{
|
||||
if(bset->nslots) {
|
||||
memset(bset->slots, 0, bset->nslots * sizeof(curl_uint64_t));
|
||||
bset->first_slot_used = UINT_MAX;
|
||||
memset(bset->slots, 0, bset->nslots * sizeof(uint64_t));
|
||||
bset->first_slot_used = UINT32_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Curl_uint_bset_add(struct uint_bset *bset, unsigned int i)
|
||||
bool Curl_uint32_bset_add(struct uint32_bset *bset, uint32_t i)
|
||||
{
|
||||
unsigned int islot = i / 64;
|
||||
uint32_t islot = i / 64;
|
||||
if(islot >= bset->nslots)
|
||||
return FALSE;
|
||||
bset->slots[islot] |= ((curl_uint64_t)1 << (i % 64));
|
||||
bset->slots[islot] |= ((uint64_t)1 << (i % 64));
|
||||
if(islot < bset->first_slot_used)
|
||||
bset->first_slot_used = islot;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void Curl_uint_bset_remove(struct uint_bset *bset, unsigned int i)
|
||||
void Curl_uint32_bset_remove(struct uint32_bset *bset, uint32_t i)
|
||||
{
|
||||
size_t islot = i / 64;
|
||||
if(islot < bset->nslots)
|
||||
bset->slots[islot] &= ~((curl_uint64_t)1 << (i % 64));
|
||||
bset->slots[islot] &= ~((uint64_t)1 << (i % 64));
|
||||
}
|
||||
|
||||
|
||||
bool Curl_uint_bset_contains(struct uint_bset *bset, unsigned int i)
|
||||
bool Curl_uint32_bset_contains(struct uint32_bset *bset, uint32_t i)
|
||||
{
|
||||
unsigned int islot = i / 64;
|
||||
uint32_t islot = i / 64;
|
||||
if(islot >= bset->nslots)
|
||||
return FALSE;
|
||||
return (bset->slots[islot] & ((curl_uint64_t)1 << (i % 64))) != 0;
|
||||
return (bset->slots[islot] & ((uint64_t)1 << (i % 64))) != 0;
|
||||
}
|
||||
|
||||
|
||||
bool Curl_uint_bset_first(struct uint_bset *bset, unsigned int *pfirst)
|
||||
bool Curl_uint32_bset_first(struct uint32_bset *bset, uint32_t *pfirst)
|
||||
{
|
||||
unsigned int i;
|
||||
uint32_t i;
|
||||
for(i = bset->first_slot_used; i < bset->nslots; ++i) {
|
||||
if(bset->slots[i]) {
|
||||
*pfirst = (i * 64) + CURL_CTZ64(bset->slots[i]);
|
||||
@@ -150,15 +150,15 @@ bool Curl_uint_bset_first(struct uint_bset *bset, unsigned int *pfirst)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
bset->first_slot_used = *pfirst = UINT_MAX;
|
||||
bset->first_slot_used = *pfirst = UINT32_MAX;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool Curl_uint_bset_next(struct uint_bset *bset, unsigned int last,
|
||||
unsigned int *pnext)
|
||||
bool Curl_uint32_bset_next(struct uint32_bset *bset, uint32_t last,
|
||||
uint32_t *pnext)
|
||||
{
|
||||
unsigned int islot;
|
||||
curl_uint64_t x;
|
||||
uint32_t islot;
|
||||
uint64_t x;
|
||||
|
||||
++last; /* look for number one higher than last */
|
||||
islot = last / 64; /* the slot this would be in */
|
||||
@@ -178,42 +178,42 @@ bool Curl_uint_bset_next(struct uint_bset *bset, unsigned int last,
|
||||
}
|
||||
}
|
||||
}
|
||||
*pnext = UINT_MAX; /* a value we cannot store */
|
||||
*pnext = UINT32_MAX; /* a value we cannot store */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef CURL_POPCOUNT64_IMPLEMENT
|
||||
unsigned int Curl_popcount64(curl_uint64_t x)
|
||||
uint32_t Curl_popcount64(uint64_t x)
|
||||
{
|
||||
/* Compute the "Hamming Distance" between 'x' and 0,
|
||||
* which is the number of set bits in 'x'.
|
||||
* See: https://en.wikipedia.org/wiki/Hamming_weight */
|
||||
const curl_uint64_t m1 = 0x5555555555555555LL; /* 0101+ */
|
||||
const curl_uint64_t m2 = 0x3333333333333333LL; /* 00110011+ */
|
||||
const curl_uint64_t m4 = 0x0f0f0f0f0f0f0f0fLL; /* 00001111+ */
|
||||
const uint64_t m1 = 0x5555555555555555LL; /* 0101+ */
|
||||
const uint64_t m2 = 0x3333333333333333LL; /* 00110011+ */
|
||||
const uint64_t m4 = 0x0f0f0f0f0f0f0f0fLL; /* 00001111+ */
|
||||
/* 1 + 256^1 + 256^2 + 256^3 + ... + 256^7 */
|
||||
const curl_uint64_t h01 = 0x0101010101010101LL;
|
||||
const uint64_t h01 = 0x0101010101010101LL;
|
||||
x -= (x >> 1) & m1; /* replace every 2 bits with bits present */
|
||||
x = (x & m2) + ((x >> 2) & m2); /* replace every nibble with bits present */
|
||||
x = (x + (x >> 4)) & m4; /* replace every byte with bits present */
|
||||
/* top 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ... which makes the
|
||||
* top byte the sum of all individual 8 bytes, throw away the rest */
|
||||
return (unsigned int)((x * h01) >> 56);
|
||||
return (uint32_t)((x * h01) >> 56);
|
||||
}
|
||||
#endif /* CURL_POPCOUNT64_IMPLEMENT */
|
||||
|
||||
|
||||
#ifdef CURL_CTZ64_IMPLEMENT
|
||||
unsigned int Curl_ctz64(curl_uint64_t x)
|
||||
uint32_t Curl_ctz64(uint64_t x)
|
||||
{
|
||||
/* count trailing zeros in a curl_uint64_t.
|
||||
/* count trailing zeros in a uint64_t.
|
||||
* divide and conquer to find the number of lower 0 bits */
|
||||
const curl_uint64_t ml32 = 0xFFFFFFFF; /* lower 32 bits */
|
||||
const curl_uint64_t ml16 = 0x0000FFFF; /* lower 16 bits */
|
||||
const curl_uint64_t ml8 = 0x000000FF; /* lower 8 bits */
|
||||
const curl_uint64_t ml4 = 0x0000000F; /* lower 4 bits */
|
||||
const curl_uint64_t ml2 = 0x00000003; /* lower 2 bits */
|
||||
unsigned int n;
|
||||
const uint64_t ml32 = 0xFFFFFFFF; /* lower 32 bits */
|
||||
const uint64_t ml16 = 0x0000FFFF; /* lower 16 bits */
|
||||
const uint64_t ml8 = 0x000000FF; /* lower 8 bits */
|
||||
const uint64_t ml4 = 0x0000000F; /* lower 4 bits */
|
||||
const uint64_t ml2 = 0x00000003; /* lower 2 bits */
|
||||
uint32_t n;
|
||||
|
||||
if(!x)
|
||||
return 64;
|
||||
@@ -238,6 +238,6 @@ unsigned int Curl_ctz64(curl_uint64_t x)
|
||||
n = n + 2;
|
||||
x = x >> 2;
|
||||
}
|
||||
return n - (unsigned int)(x & 1);
|
||||
return n - (uint32_t)(x & 1);
|
||||
}
|
||||
#endif /* CURL_CTZ64_IMPLEMENT */
|
||||
|
||||
@@ -39,51 +39,51 @@
|
||||
* the price of slightly slower operations.
|
||||
*/
|
||||
|
||||
struct uint_bset {
|
||||
curl_uint64_t *slots;
|
||||
unsigned int nslots;
|
||||
unsigned int first_slot_used;
|
||||
struct uint32_bset {
|
||||
uint64_t *slots;
|
||||
uint32_t nslots;
|
||||
uint32_t first_slot_used;
|
||||
#ifdef DEBUGBUILD
|
||||
int init;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Initialize the bitset with capacity 0. */
|
||||
void Curl_uint_bset_init(struct uint_bset *bset);
|
||||
void Curl_uint32_bset_init(struct uint32_bset *bset);
|
||||
|
||||
/* Resize the bitset capacity to hold numbers from 0 to `nmax`,
|
||||
* which rounds up `nmax` to the next multiple of 64. */
|
||||
CURLcode Curl_uint_bset_resize(struct uint_bset *bset, unsigned int nmax);
|
||||
CURLcode Curl_uint32_bset_resize(struct uint32_bset *bset, uint32_t nmax);
|
||||
|
||||
/* Destroy the bitset, freeing all resources. */
|
||||
void Curl_uint_bset_destroy(struct uint_bset *bset);
|
||||
void Curl_uint32_bset_destroy(struct uint32_bset *bset);
|
||||
|
||||
/* Get the bitset capacity, e.g. can hold numbers from 0 to capacity - 1. */
|
||||
unsigned int Curl_uint_bset_capacity(struct uint_bset *bset);
|
||||
uint32_t Curl_uint32_bset_capacity(struct uint32_bset *bset);
|
||||
|
||||
/* Get the cardinality of the bitset, e.g. numbers present in the set. */
|
||||
unsigned int Curl_uint_bset_count(struct uint_bset *bset);
|
||||
uint32_t Curl_uint32_bset_count(struct uint32_bset *bset);
|
||||
|
||||
/* TRUE of bitset is empty */
|
||||
bool Curl_uint_bset_empty(struct uint_bset *bset);
|
||||
bool Curl_uint32_bset_empty(struct uint32_bset *bset);
|
||||
|
||||
/* Clear the bitset, making it empty. */
|
||||
void Curl_uint_bset_clear(struct uint_bset *bset);
|
||||
void Curl_uint32_bset_clear(struct uint32_bset *bset);
|
||||
|
||||
/* Add the number `i` to the bitset. Return FALSE if the number is
|
||||
* outside the set's capacity.
|
||||
* Numbers can be added more than once, without making a difference. */
|
||||
bool Curl_uint_bset_add(struct uint_bset *bset, unsigned int i);
|
||||
bool Curl_uint32_bset_add(struct uint32_bset *bset, uint32_t i);
|
||||
|
||||
/* Remove the number `i` from the bitset. */
|
||||
void Curl_uint_bset_remove(struct uint_bset *bset, unsigned int i);
|
||||
void Curl_uint32_bset_remove(struct uint32_bset *bset, uint32_t i);
|
||||
|
||||
/* Return TRUE if the bitset contains number `i`. */
|
||||
bool Curl_uint_bset_contains(struct uint_bset *bset, unsigned int i);
|
||||
bool Curl_uint32_bset_contains(struct uint32_bset *bset, uint32_t i);
|
||||
|
||||
/* Get the first number in the bitset, e.g. the smallest.
|
||||
* Returns FALSE when the bitset is empty. */
|
||||
bool Curl_uint_bset_first(struct uint_bset *bset, unsigned int *pfirst);
|
||||
bool Curl_uint32_bset_first(struct uint32_bset *bset, uint32_t *pfirst);
|
||||
|
||||
/* Get the next number in the bitset, following `last` in natural order.
|
||||
* Put another way, this is the smallest number greater than `last` in
|
||||
@@ -96,20 +96,20 @@ bool Curl_uint_bset_first(struct uint_bset *bset, unsigned int *pfirst);
|
||||
* - added numbers lower than 'last' will not show up.
|
||||
* - removed numbers lower or equal to 'last' will not show up.
|
||||
* - removed numbers higher than 'last' will not be visited. */
|
||||
bool Curl_uint_bset_next(struct uint_bset *bset, unsigned int last,
|
||||
unsigned int *pnext);
|
||||
bool Curl_uint32_bset_next(struct uint32_bset *bset, uint32_t last,
|
||||
uint32_t *pnext);
|
||||
|
||||
|
||||
#ifndef CURL_POPCOUNT64
|
||||
#define CURL_POPCOUNT64(x) Curl_popcount64(x)
|
||||
#define CURL_POPCOUNT64_IMPLEMENT
|
||||
unsigned int Curl_popcount64(curl_uint64_t x);
|
||||
uint32_t Curl_popcount64(uint64_t x);
|
||||
#endif /* !CURL_POPCOUNT64 */
|
||||
|
||||
#ifndef CURL_CTZ64
|
||||
#define CURL_CTZ64(x) Curl_ctz64(x)
|
||||
#define CURL_CTZ64_IMPLEMENT
|
||||
unsigned int Curl_ctz64(curl_uint64_t x);
|
||||
uint32_t Curl_ctz64(uint64_t x);
|
||||
#endif /* !CURL_CTZ64 */
|
||||
|
||||
#endif /* HEADER_CURL_UINT_BSET_H */
|
||||
|
||||
@@ -34,10 +34,10 @@
|
||||
|
||||
/* random patterns for API verification */
|
||||
#ifdef DEBUGBUILD
|
||||
#define CURL_UINTHASHINIT 0x7117e779
|
||||
#define CURL_UINT32_HASHINIT 0x7117e779
|
||||
#endif
|
||||
|
||||
static unsigned int uint_hash_hash(unsigned int id, unsigned int slots)
|
||||
static uint32_t uint32_hash_hash(uint32_t id, uint32_t slots)
|
||||
{
|
||||
return (id % slots);
|
||||
}
|
||||
@@ -46,12 +46,12 @@ static unsigned int uint_hash_hash(unsigned int id, unsigned int slots)
|
||||
struct uint_hash_entry {
|
||||
struct uint_hash_entry *next;
|
||||
void *value;
|
||||
unsigned int id;
|
||||
uint32_t id;
|
||||
};
|
||||
|
||||
void Curl_uint_hash_init(struct uint_hash *h,
|
||||
unsigned int slots,
|
||||
Curl_uint_hash_dtor *dtor)
|
||||
void Curl_uint32_hash_init(struct uint_hash *h,
|
||||
uint32_t slots,
|
||||
Curl_uint32_hash_dtor *dtor)
|
||||
{
|
||||
DEBUGASSERT(h);
|
||||
DEBUGASSERT(slots);
|
||||
@@ -61,11 +61,11 @@ void Curl_uint_hash_init(struct uint_hash *h,
|
||||
h->size = 0;
|
||||
h->slots = slots;
|
||||
#ifdef DEBUGBUILD
|
||||
h->init = CURL_UINTHASHINIT;
|
||||
h->init = CURL_UINT32_HASHINIT;
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct uint_hash_entry *uint_hash_mk_entry(unsigned int id, void *value)
|
||||
static struct uint_hash_entry *uint32_hash_mk_entry(uint32_t id, void *value)
|
||||
{
|
||||
struct uint_hash_entry *e;
|
||||
|
||||
@@ -79,8 +79,8 @@ static struct uint_hash_entry *uint_hash_mk_entry(unsigned int id, void *value)
|
||||
return e;
|
||||
}
|
||||
|
||||
static void uint_hash_entry_clear(struct uint_hash *h,
|
||||
struct uint_hash_entry *e)
|
||||
static void uint32_hash_entry_clear(struct uint_hash *h,
|
||||
struct uint_hash_entry *e)
|
||||
{
|
||||
DEBUGASSERT(h);
|
||||
DEBUGASSERT(e);
|
||||
@@ -91,78 +91,78 @@ static void uint_hash_entry_clear(struct uint_hash *h,
|
||||
}
|
||||
}
|
||||
|
||||
static void uint_hash_entry_destroy(struct uint_hash *h,
|
||||
struct uint_hash_entry *e)
|
||||
static void uint32_hash_entry_destroy(struct uint_hash *h,
|
||||
struct uint_hash_entry *e)
|
||||
{
|
||||
uint_hash_entry_clear(h, e);
|
||||
uint32_hash_entry_clear(h, e);
|
||||
free(e);
|
||||
}
|
||||
|
||||
static void uint_hash_entry_unlink(struct uint_hash *h,
|
||||
struct uint_hash_entry **he_anchor,
|
||||
struct uint_hash_entry *he)
|
||||
static void uint32_hash_entry_unlink(struct uint_hash *h,
|
||||
struct uint_hash_entry **he_anchor,
|
||||
struct uint_hash_entry *he)
|
||||
{
|
||||
*he_anchor = he->next;
|
||||
--h->size;
|
||||
}
|
||||
|
||||
static void uint_hash_elem_link(struct uint_hash *h,
|
||||
struct uint_hash_entry **he_anchor,
|
||||
struct uint_hash_entry *he)
|
||||
static void uint32_hash_elem_link(struct uint_hash *h,
|
||||
struct uint_hash_entry **he_anchor,
|
||||
struct uint_hash_entry *he)
|
||||
{
|
||||
he->next = *he_anchor;
|
||||
*he_anchor = he;
|
||||
++h->size;
|
||||
}
|
||||
|
||||
#define CURL_UINT_HASH_SLOT(h,id) h->table[uint_hash_hash(id, h->slots)]
|
||||
#define CURL_UINT_HASH_SLOT_ADDR(h,id) &CURL_UINT_HASH_SLOT(h,id)
|
||||
#define CURL_UINT32_HASH_SLOT(h,id) h->table[uint32_hash_hash(id, h->slots)]
|
||||
#define CURL_UINT32_HASH_SLOT_ADDR(h,id) &CURL_UINT32_HASH_SLOT(h,id)
|
||||
|
||||
bool Curl_uint_hash_set(struct uint_hash *h, unsigned int id, void *value)
|
||||
bool Curl_uint32_hash_set(struct uint_hash *h, uint32_t id, void *value)
|
||||
{
|
||||
struct uint_hash_entry *he, **slot;
|
||||
|
||||
DEBUGASSERT(h);
|
||||
DEBUGASSERT(h->slots);
|
||||
DEBUGASSERT(h->init == CURL_UINTHASHINIT);
|
||||
DEBUGASSERT(h->init == CURL_UINT32_HASHINIT);
|
||||
if(!h->table) {
|
||||
h->table = calloc(h->slots, sizeof(*he));
|
||||
if(!h->table)
|
||||
return FALSE; /* OOM */
|
||||
}
|
||||
|
||||
slot = CURL_UINT_HASH_SLOT_ADDR(h, id);
|
||||
slot = CURL_UINT32_HASH_SLOT_ADDR(h, id);
|
||||
for(he = *slot; he; he = he->next) {
|
||||
if(he->id == id) {
|
||||
/* existing key entry, overwrite by clearing old pointer */
|
||||
uint_hash_entry_clear(h, he);
|
||||
uint32_hash_entry_clear(h, he);
|
||||
he->value = value;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
he = uint_hash_mk_entry(id, value);
|
||||
he = uint32_hash_mk_entry(id, value);
|
||||
if(!he)
|
||||
return FALSE; /* OOM */
|
||||
|
||||
uint_hash_elem_link(h, slot, he);
|
||||
uint32_hash_elem_link(h, slot, he);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool Curl_uint_hash_remove(struct uint_hash *h, unsigned int id)
|
||||
bool Curl_uint32_hash_remove(struct uint_hash *h, uint32_t id)
|
||||
{
|
||||
DEBUGASSERT(h);
|
||||
DEBUGASSERT(h->slots);
|
||||
DEBUGASSERT(h->init == CURL_UINTHASHINIT);
|
||||
DEBUGASSERT(h->init == CURL_UINT32_HASHINIT);
|
||||
if(h->table) {
|
||||
struct uint_hash_entry *he, **he_anchor;
|
||||
|
||||
he_anchor = CURL_UINT_HASH_SLOT_ADDR(h, id);
|
||||
he_anchor = CURL_UINT32_HASH_SLOT_ADDR(h, id);
|
||||
while(*he_anchor) {
|
||||
he = *he_anchor;
|
||||
if(id == he->id) {
|
||||
uint_hash_entry_unlink(h, he_anchor, he);
|
||||
uint_hash_entry_destroy(h, he);
|
||||
uint32_hash_entry_unlink(h, he_anchor, he);
|
||||
uint32_hash_entry_destroy(h, he);
|
||||
return TRUE;
|
||||
}
|
||||
he_anchor = &he->next;
|
||||
@@ -171,14 +171,14 @@ bool Curl_uint_hash_remove(struct uint_hash *h, unsigned int id)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void *Curl_uint_hash_get(struct uint_hash *h, unsigned int id)
|
||||
void *Curl_uint32_hash_get(struct uint_hash *h, uint32_t id)
|
||||
{
|
||||
DEBUGASSERT(h);
|
||||
DEBUGASSERT(h->init == CURL_UINTHASHINIT);
|
||||
DEBUGASSERT(h->init == CURL_UINT32_HASHINIT);
|
||||
if(h->table) {
|
||||
struct uint_hash_entry *he;
|
||||
DEBUGASSERT(h->slots);
|
||||
he = CURL_UINT_HASH_SLOT(h, id);
|
||||
he = CURL_UINT32_HASH_SLOT(h, id);
|
||||
while(he) {
|
||||
if(id == he->id) {
|
||||
return he->value;
|
||||
@@ -194,28 +194,28 @@ static void uint_hash_clear(struct uint_hash *h)
|
||||
if(h && h->table) {
|
||||
struct uint_hash_entry *he, **he_anchor;
|
||||
size_t i;
|
||||
DEBUGASSERT(h->init == CURL_UINTHASHINIT);
|
||||
DEBUGASSERT(h->init == CURL_UINT32_HASHINIT);
|
||||
for(i = 0; i < h->slots; ++i) {
|
||||
he_anchor = &h->table[i];
|
||||
while(*he_anchor) {
|
||||
he = *he_anchor;
|
||||
uint_hash_entry_unlink(h, he_anchor, he);
|
||||
uint_hash_entry_destroy(h, he);
|
||||
uint32_hash_entry_unlink(h, he_anchor, he);
|
||||
uint32_hash_entry_destroy(h, he);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UNITTESTS
|
||||
UNITTEST void Curl_uint_hash_clear(struct uint_hash *h)
|
||||
UNITTEST void Curl_uint32_hash_clear(struct uint_hash *h)
|
||||
{
|
||||
uint_hash_clear(h);
|
||||
}
|
||||
#endif
|
||||
|
||||
void Curl_uint_hash_destroy(struct uint_hash *h)
|
||||
void Curl_uint32_hash_destroy(struct uint_hash *h)
|
||||
{
|
||||
DEBUGASSERT(h->init == CURL_UINTHASHINIT);
|
||||
DEBUGASSERT(h->init == CURL_UINT32_HASHINIT);
|
||||
if(h->table) {
|
||||
uint_hash_clear(h);
|
||||
Curl_safefree(h->table);
|
||||
@@ -224,20 +224,20 @@ void Curl_uint_hash_destroy(struct uint_hash *h)
|
||||
h->slots = 0;
|
||||
}
|
||||
|
||||
unsigned int Curl_uint_hash_count(struct uint_hash *h)
|
||||
uint32_t Curl_uint32_hash_count(struct uint_hash *h)
|
||||
{
|
||||
DEBUGASSERT(h->init == CURL_UINTHASHINIT);
|
||||
DEBUGASSERT(h->init == CURL_UINT32_HASHINIT);
|
||||
return h->size;
|
||||
}
|
||||
|
||||
void Curl_uint_hash_visit(struct uint_hash *h,
|
||||
Curl_uint_hash_visit_cb *cb,
|
||||
void *user_data)
|
||||
void Curl_uint32_hash_visit(struct uint_hash *h,
|
||||
Curl_uint32_hash_visit_cb *cb,
|
||||
void *user_data)
|
||||
{
|
||||
if(h && h->table && cb) {
|
||||
struct uint_hash_entry *he;
|
||||
size_t i;
|
||||
DEBUGASSERT(h->init == CURL_UINTHASHINIT);
|
||||
DEBUGASSERT(h->init == CURL_UINT32_HASHINIT);
|
||||
for(i = 0; i < h->slots; ++i) {
|
||||
for(he = h->table[i]; he; he = he->next) {
|
||||
if(!cb(he->id, he->value, user_data))
|
||||
|
||||
@@ -30,39 +30,39 @@
|
||||
|
||||
#include "llist.h"
|
||||
|
||||
/* A version with unsigned int as key */
|
||||
typedef void Curl_uint_hash_dtor(unsigned int id, void *value);
|
||||
/* A version with uint32_t as key */
|
||||
typedef void Curl_uint32_hash_dtor(uint32_t id, void *value);
|
||||
struct uint_hash_entry;
|
||||
|
||||
/* Hash for `unsigned int` as key */
|
||||
/* Hash for `uint32_t` as key */
|
||||
struct uint_hash {
|
||||
struct uint_hash_entry **table;
|
||||
Curl_uint_hash_dtor *dtor;
|
||||
unsigned int slots;
|
||||
unsigned int size;
|
||||
Curl_uint32_hash_dtor *dtor;
|
||||
uint32_t slots;
|
||||
uint32_t size;
|
||||
#ifdef DEBUGBUILD
|
||||
int init;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
void Curl_uint_hash_init(struct uint_hash *h,
|
||||
unsigned int slots,
|
||||
Curl_uint_hash_dtor *dtor);
|
||||
void Curl_uint_hash_destroy(struct uint_hash *h);
|
||||
void Curl_uint_hash_clear(struct uint_hash *h);
|
||||
void Curl_uint32_hash_init(struct uint_hash *h,
|
||||
uint32_t slots,
|
||||
Curl_uint32_hash_dtor *dtor);
|
||||
void Curl_uint32_hash_destroy(struct uint_hash *h);
|
||||
void Curl_uint32_hash_clear(struct uint_hash *h);
|
||||
|
||||
bool Curl_uint_hash_set(struct uint_hash *h, unsigned int id, void *value);
|
||||
bool Curl_uint_hash_remove(struct uint_hash *h, unsigned int id);
|
||||
void *Curl_uint_hash_get(struct uint_hash *h, unsigned int id);
|
||||
unsigned int Curl_uint_hash_count(struct uint_hash *h);
|
||||
bool Curl_uint32_hash_set(struct uint_hash *h, uint32_t id, void *value);
|
||||
bool Curl_uint32_hash_remove(struct uint_hash *h, uint32_t id);
|
||||
void *Curl_uint32_hash_get(struct uint_hash *h, uint32_t id);
|
||||
uint32_t Curl_uint32_hash_count(struct uint_hash *h);
|
||||
|
||||
|
||||
typedef bool Curl_uint_hash_visit_cb(unsigned int id, void *value,
|
||||
void *user_data);
|
||||
typedef bool Curl_uint32_hash_visit_cb(uint32_t id, void *value,
|
||||
void *user_data);
|
||||
|
||||
void Curl_uint_hash_visit(struct uint_hash *h,
|
||||
Curl_uint_hash_visit_cb *cb,
|
||||
void *user_data);
|
||||
void Curl_uint32_hash_visit(struct uint_hash *h,
|
||||
Curl_uint32_hash_visit_cb *cb,
|
||||
void *user_data);
|
||||
|
||||
#endif /* HEADER_CURL_UINT_HASH_H */
|
||||
|
||||
@@ -31,33 +31,33 @@
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define CURL_UINT_SPBSET_MAGIC 0x70737362
|
||||
#define CURL_UINT32_SPBSET_MAGIC 0x70737362
|
||||
#endif
|
||||
|
||||
/* Clear the bitset, making it empty. */
|
||||
UNITTEST void Curl_uint_spbset_clear(struct uint_spbset *bset);
|
||||
UNITTEST void Curl_uint32_spbset_clear(struct uint32_spbset *bset);
|
||||
|
||||
void Curl_uint_spbset_init(struct uint_spbset *bset)
|
||||
void Curl_uint32_spbset_init(struct uint32_spbset *bset)
|
||||
{
|
||||
memset(bset, 0, sizeof(*bset));
|
||||
#ifdef DEBUGBUILD
|
||||
bset->init = CURL_UINT_SPBSET_MAGIC;
|
||||
bset->init = CURL_UINT32_SPBSET_MAGIC;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Curl_uint_spbset_destroy(struct uint_spbset *bset)
|
||||
void Curl_uint32_spbset_destroy(struct uint32_spbset *bset)
|
||||
{
|
||||
DEBUGASSERT(bset->init == CURL_UINT_SPBSET_MAGIC);
|
||||
Curl_uint_spbset_clear(bset);
|
||||
DEBUGASSERT(bset->init == CURL_UINT32_SPBSET_MAGIC);
|
||||
Curl_uint32_spbset_clear(bset);
|
||||
}
|
||||
|
||||
unsigned int Curl_uint_spbset_count(struct uint_spbset *bset)
|
||||
uint32_t Curl_uint32_spbset_count(struct uint32_spbset *bset)
|
||||
{
|
||||
struct uint_spbset_chunk *chunk;
|
||||
unsigned int i, n = 0;
|
||||
struct uint32_spbset_chunk *chunk;
|
||||
uint32_t i, n = 0;
|
||||
|
||||
for(chunk = &bset->head; chunk; chunk = chunk->next) {
|
||||
for(i = 0; i < CURL_UINT_SPBSET_CH_SLOTS; ++i) {
|
||||
for(i = 0; i < CURL_UINT32_SPBSET_CH_SLOTS; ++i) {
|
||||
if(chunk->slots[i])
|
||||
n += CURL_POPCOUNT64(chunk->slots[i]);
|
||||
}
|
||||
@@ -65,13 +65,13 @@ unsigned int Curl_uint_spbset_count(struct uint_spbset *bset)
|
||||
return n;
|
||||
}
|
||||
|
||||
bool Curl_uint_spbset_empty(struct uint_spbset *bset)
|
||||
bool Curl_uint32_spbset_empty(struct uint32_spbset *bset)
|
||||
{
|
||||
struct uint_spbset_chunk *chunk;
|
||||
unsigned int i;
|
||||
struct uint32_spbset_chunk *chunk;
|
||||
uint32_t i;
|
||||
|
||||
for(chunk = &bset->head; chunk; chunk = chunk->next) {
|
||||
for(i = 0; i < CURL_UINT_SPBSET_CH_SLOTS; ++i) {
|
||||
for(i = 0; i < CURL_UINT32_SPBSET_CH_SLOTS; ++i) {
|
||||
if(chunk->slots[i])
|
||||
return FALSE;
|
||||
}
|
||||
@@ -79,9 +79,9 @@ bool Curl_uint_spbset_empty(struct uint_spbset *bset)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
UNITTEST void Curl_uint_spbset_clear(struct uint_spbset *bset)
|
||||
UNITTEST void Curl_uint32_spbset_clear(struct uint32_spbset *bset)
|
||||
{
|
||||
struct uint_spbset_chunk *next, *chunk;
|
||||
struct uint32_spbset_chunk *next, *chunk;
|
||||
|
||||
for(chunk = bset->head.next; chunk; chunk = next) {
|
||||
next = chunk->next;
|
||||
@@ -91,11 +91,11 @@ UNITTEST void Curl_uint_spbset_clear(struct uint_spbset *bset)
|
||||
}
|
||||
|
||||
|
||||
static struct uint_spbset_chunk *
|
||||
uint_spbset_get_chunk(struct uint_spbset *bset, unsigned int i, bool grow)
|
||||
static struct uint32_spbset_chunk *
|
||||
uint32_spbset_get_chunk(struct uint32_spbset *bset, uint32_t i, bool grow)
|
||||
{
|
||||
struct uint_spbset_chunk *chunk, **panchor = NULL;
|
||||
unsigned int i_offset = (i & ~CURL_UINT_SPBSET_CH_MASK);
|
||||
struct uint32_spbset_chunk *chunk, **panchor = NULL;
|
||||
uint32_t i_offset = (i & ~CURL_UINT32_SPBSET_CH_MASK);
|
||||
|
||||
if(!bset)
|
||||
return NULL;
|
||||
@@ -134,61 +134,61 @@ uint_spbset_get_chunk(struct uint_spbset *bset, unsigned int i, bool grow)
|
||||
}
|
||||
|
||||
|
||||
bool Curl_uint_spbset_add(struct uint_spbset *bset, unsigned int i)
|
||||
bool Curl_uint32_spbset_add(struct uint32_spbset *bset, uint32_t i)
|
||||
{
|
||||
struct uint_spbset_chunk *chunk;
|
||||
unsigned int i_chunk;
|
||||
struct uint32_spbset_chunk *chunk;
|
||||
uint32_t i_chunk;
|
||||
|
||||
chunk = uint_spbset_get_chunk(bset, i, TRUE);
|
||||
chunk = uint32_spbset_get_chunk(bset, i, TRUE);
|
||||
if(!chunk)
|
||||
return FALSE;
|
||||
|
||||
DEBUGASSERT(i >= chunk->offset);
|
||||
i_chunk = (i - chunk->offset);
|
||||
DEBUGASSERT((i_chunk / 64) < CURL_UINT_SPBSET_CH_SLOTS);
|
||||
chunk->slots[(i_chunk / 64)] |= ((curl_uint64_t)1 << (i_chunk % 64));
|
||||
DEBUGASSERT((i_chunk / 64) < CURL_UINT32_SPBSET_CH_SLOTS);
|
||||
chunk->slots[(i_chunk / 64)] |= ((uint64_t)1 << (i_chunk % 64));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void Curl_uint_spbset_remove(struct uint_spbset *bset, unsigned int i)
|
||||
void Curl_uint32_spbset_remove(struct uint32_spbset *bset, uint32_t i)
|
||||
{
|
||||
struct uint_spbset_chunk *chunk;
|
||||
unsigned int i_chunk;
|
||||
struct uint32_spbset_chunk *chunk;
|
||||
uint32_t i_chunk;
|
||||
|
||||
chunk = uint_spbset_get_chunk(bset, i, FALSE);
|
||||
chunk = uint32_spbset_get_chunk(bset, i, FALSE);
|
||||
if(chunk) {
|
||||
DEBUGASSERT(i >= chunk->offset);
|
||||
i_chunk = (i - chunk->offset);
|
||||
DEBUGASSERT((i_chunk / 64) < CURL_UINT_SPBSET_CH_SLOTS);
|
||||
chunk->slots[(i_chunk / 64)] &= ~((curl_uint64_t)1 << (i_chunk % 64));
|
||||
DEBUGASSERT((i_chunk / 64) < CURL_UINT32_SPBSET_CH_SLOTS);
|
||||
chunk->slots[(i_chunk / 64)] &= ~((uint64_t)1 << (i_chunk % 64));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Curl_uint_spbset_contains(struct uint_spbset *bset, unsigned int i)
|
||||
bool Curl_uint32_spbset_contains(struct uint32_spbset *bset, uint32_t i)
|
||||
{
|
||||
struct uint_spbset_chunk *chunk;
|
||||
unsigned int i_chunk;
|
||||
struct uint32_spbset_chunk *chunk;
|
||||
uint32_t i_chunk;
|
||||
|
||||
chunk = uint_spbset_get_chunk(bset, i, FALSE);
|
||||
chunk = uint32_spbset_get_chunk(bset, i, FALSE);
|
||||
if(chunk) {
|
||||
DEBUGASSERT(i >= chunk->offset);
|
||||
i_chunk = (i - chunk->offset);
|
||||
DEBUGASSERT((i_chunk / 64) < CURL_UINT_SPBSET_CH_SLOTS);
|
||||
DEBUGASSERT((i_chunk / 64) < CURL_UINT32_SPBSET_CH_SLOTS);
|
||||
return (chunk->slots[i_chunk / 64] &
|
||||
((curl_uint64_t)1 << (i_chunk % 64))) != 0;
|
||||
((uint64_t)1 << (i_chunk % 64))) != 0;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool Curl_uint_spbset_first(struct uint_spbset *bset, unsigned int *pfirst)
|
||||
bool Curl_uint32_spbset_first(struct uint32_spbset *bset, uint32_t *pfirst)
|
||||
{
|
||||
struct uint_spbset_chunk *chunk;
|
||||
unsigned int i;
|
||||
struct uint32_spbset_chunk *chunk;
|
||||
uint32_t i;
|
||||
|
||||
for(chunk = &bset->head; chunk; chunk = chunk->next) {
|
||||
for(i = 0; i < CURL_UINT_SPBSET_CH_SLOTS; ++i) {
|
||||
for(i = 0; i < CURL_UINT32_SPBSET_CH_SLOTS; ++i) {
|
||||
if(chunk->slots[i]) {
|
||||
*pfirst = chunk->offset + ((i * 64) + CURL_CTZ64(chunk->slots[i]));
|
||||
return TRUE;
|
||||
@@ -200,29 +200,29 @@ bool Curl_uint_spbset_first(struct uint_spbset *bset, unsigned int *pfirst)
|
||||
}
|
||||
|
||||
|
||||
static bool uint_spbset_chunk_first(struct uint_spbset_chunk *chunk,
|
||||
unsigned int *pfirst)
|
||||
static bool uint32_spbset_chunk_first(struct uint32_spbset_chunk *chunk,
|
||||
uint32_t *pfirst)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; i < CURL_UINT_SPBSET_CH_SLOTS; ++i) {
|
||||
uint32_t i;
|
||||
for(i = 0; i < CURL_UINT32_SPBSET_CH_SLOTS; ++i) {
|
||||
if(chunk->slots[i]) {
|
||||
*pfirst = chunk->offset + ((i * 64) + CURL_CTZ64(chunk->slots[i]));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
*pfirst = UINT_MAX; /* a value we cannot store */
|
||||
*pfirst = UINT32_MAX; /* a value we cannot store */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static bool uint_spbset_chunk_next(struct uint_spbset_chunk *chunk,
|
||||
unsigned int last,
|
||||
unsigned int *pnext)
|
||||
static bool uint32_spbset_chunk_next(struct uint32_spbset_chunk *chunk,
|
||||
uint32_t last,
|
||||
uint32_t *pnext)
|
||||
{
|
||||
if(chunk->offset <= last) {
|
||||
curl_uint64_t x;
|
||||
unsigned int i = ((last - chunk->offset) / 64);
|
||||
if(i < CURL_UINT_SPBSET_CH_SLOTS) {
|
||||
uint64_t x;
|
||||
uint32_t i = ((last - chunk->offset) / 64);
|
||||
if(i < CURL_UINT32_SPBSET_CH_SLOTS) {
|
||||
x = (chunk->slots[i] >> (last % 64));
|
||||
if(x) {
|
||||
/* more bits set, next is `last` + trailing0s of the shifted slot */
|
||||
@@ -230,7 +230,7 @@ static bool uint_spbset_chunk_next(struct uint_spbset_chunk *chunk,
|
||||
return TRUE;
|
||||
}
|
||||
/* no more bits set in the last slot, scan forward */
|
||||
for(i = i + 1; i < CURL_UINT_SPBSET_CH_SLOTS; ++i) {
|
||||
for(i = i + 1; i < CURL_UINT32_SPBSET_CH_SLOTS; ++i) {
|
||||
if(chunk->slots[i]) {
|
||||
*pnext = chunk->offset + ((i * 64) + CURL_CTZ64(chunk->slots[i]));
|
||||
return TRUE;
|
||||
@@ -238,18 +238,18 @@ static bool uint_spbset_chunk_next(struct uint_spbset_chunk *chunk,
|
||||
}
|
||||
}
|
||||
}
|
||||
*pnext = UINT_MAX;
|
||||
*pnext = UINT32_MAX;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool Curl_uint_spbset_next(struct uint_spbset *bset, unsigned int last,
|
||||
unsigned int *pnext)
|
||||
bool Curl_uint32_spbset_next(struct uint32_spbset *bset, uint32_t last,
|
||||
uint32_t *pnext)
|
||||
{
|
||||
struct uint_spbset_chunk *chunk;
|
||||
unsigned int last_offset;
|
||||
struct uint32_spbset_chunk *chunk;
|
||||
uint32_t last_offset;
|
||||
|
||||
++last; /* look for the next higher number */
|
||||
last_offset = (last & ~CURL_UINT_SPBSET_CH_MASK);
|
||||
last_offset = (last & ~CURL_UINT32_SPBSET_CH_MASK);
|
||||
|
||||
for(chunk = &bset->head; chunk; chunk = chunk->next) {
|
||||
if(chunk->offset >= last_offset) {
|
||||
@@ -259,17 +259,17 @@ bool Curl_uint_spbset_next(struct uint_spbset *bset, unsigned int last,
|
||||
|
||||
if(chunk && (chunk->offset == last_offset)) {
|
||||
/* is there a number higher than last in this chunk? */
|
||||
if(uint_spbset_chunk_next(chunk, last, pnext))
|
||||
if(uint32_spbset_chunk_next(chunk, last, pnext))
|
||||
return TRUE;
|
||||
/* not in this chunk */
|
||||
chunk = chunk->next;
|
||||
}
|
||||
/* look for the first in the "higher" chunks, if there are any. */
|
||||
while(chunk) {
|
||||
if(uint_spbset_chunk_first(chunk, pnext))
|
||||
if(uint32_spbset_chunk_first(chunk, pnext))
|
||||
return TRUE;
|
||||
chunk = chunk->next;
|
||||
}
|
||||
*pnext = UINT_MAX;
|
||||
*pnext = UINT32_MAX;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* A "sparse" bitset for unsigned int values.
|
||||
* It can hold any unsigned int value.
|
||||
/* A "sparse" bitset for uint32_t values.
|
||||
* It can hold any uint32_t value.
|
||||
*
|
||||
* Optimized for the case where only a small set of numbers need
|
||||
* to be kept, especially when "close" together. Then storage space
|
||||
@@ -36,48 +36,48 @@
|
||||
*/
|
||||
|
||||
/* 4 slots = 256 bits, keep this a 2^n value. */
|
||||
#define CURL_UINT_SPBSET_CH_SLOTS 4
|
||||
#define CURL_UINT_SPBSET_CH_MASK ((CURL_UINT_SPBSET_CH_SLOTS * 64) - 1)
|
||||
#define CURL_UINT32_SPBSET_CH_SLOTS 4
|
||||
#define CURL_UINT32_SPBSET_CH_MASK ((CURL_UINT32_SPBSET_CH_SLOTS * 64) - 1)
|
||||
|
||||
/* store the uint value from offset to
|
||||
* (offset + (CURL_UINT_SPBSET_CHUNK_SLOTS * 64) - 1 */
|
||||
struct uint_spbset_chunk {
|
||||
struct uint_spbset_chunk *next;
|
||||
curl_uint64_t slots[CURL_UINT_SPBSET_CH_SLOTS];
|
||||
unsigned int offset;
|
||||
* (offset + (CURL_UINT32_SPBSET_CHUNK_SLOTS * 64) - 1 */
|
||||
struct uint32_spbset_chunk {
|
||||
struct uint32_spbset_chunk *next;
|
||||
uint64_t slots[CURL_UINT32_SPBSET_CH_SLOTS];
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
struct uint_spbset {
|
||||
struct uint_spbset_chunk head;
|
||||
struct uint32_spbset {
|
||||
struct uint32_spbset_chunk head;
|
||||
#ifdef DEBUGBUILD
|
||||
int init;
|
||||
#endif
|
||||
};
|
||||
|
||||
void Curl_uint_spbset_init(struct uint_spbset *bset);
|
||||
void Curl_uint32_spbset_init(struct uint32_spbset *bset);
|
||||
|
||||
void Curl_uint_spbset_destroy(struct uint_spbset *bset);
|
||||
void Curl_uint32_spbset_destroy(struct uint32_spbset *bset);
|
||||
|
||||
/* Get the cardinality of the bitset, e.g. numbers present in the set. */
|
||||
unsigned int Curl_uint_spbset_count(struct uint_spbset *bset);
|
||||
uint32_t Curl_uint32_spbset_count(struct uint32_spbset *bset);
|
||||
|
||||
/* TRUE of bitset is empty */
|
||||
bool Curl_uint_spbset_empty(struct uint_spbset *bset);
|
||||
bool Curl_uint32_spbset_empty(struct uint32_spbset *bset);
|
||||
|
||||
/* Add the number `i` to the bitset.
|
||||
* Numbers can be added more than once, without making a difference.
|
||||
* Returns FALSE if allocations failed. */
|
||||
bool Curl_uint_spbset_add(struct uint_spbset *bset, unsigned int i);
|
||||
bool Curl_uint32_spbset_add(struct uint32_spbset *bset, uint32_t i);
|
||||
|
||||
/* Remove the number `i` from the bitset. */
|
||||
void Curl_uint_spbset_remove(struct uint_spbset *bset, unsigned int i);
|
||||
void Curl_uint32_spbset_remove(struct uint32_spbset *bset, uint32_t i);
|
||||
|
||||
/* Return TRUE if the bitset contains number `i`. */
|
||||
bool Curl_uint_spbset_contains(struct uint_spbset *bset, unsigned int i);
|
||||
bool Curl_uint32_spbset_contains(struct uint32_spbset *bset, uint32_t i);
|
||||
|
||||
/* Get the first number in the bitset, e.g. the smallest.
|
||||
* Returns FALSE when the bitset is empty. */
|
||||
bool Curl_uint_spbset_first(struct uint_spbset *bset, unsigned int *pfirst);
|
||||
bool Curl_uint32_spbset_first(struct uint32_spbset *bset, uint32_t *pfirst);
|
||||
|
||||
/* Get the next number in the bitset, following `last` in natural order.
|
||||
* Put another way, this is the smallest number greater than `last` in
|
||||
@@ -90,7 +90,7 @@ bool Curl_uint_spbset_first(struct uint_spbset *bset, unsigned int *pfirst);
|
||||
* - added numbers lower than 'last' will not show up.
|
||||
* - removed numbers lower or equal to 'last' will not show up.
|
||||
* - removed numbers higher than 'last' will not be visited. */
|
||||
bool Curl_uint_spbset_next(struct uint_spbset *bset, unsigned int last,
|
||||
unsigned int *pnext);
|
||||
bool Curl_uint32_spbset_next(struct uint32_spbset *bset, uint32_t last,
|
||||
uint32_t *pnext);
|
||||
|
||||
#endif /* HEADER_CURL_UINT_SPBSET_H */
|
||||
|
||||
@@ -30,29 +30,29 @@
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define CURL_UINT_TBL_MAGIC 0x62757473
|
||||
#define CURL_UINT32_TBL_MAGIC 0x62757473
|
||||
#endif
|
||||
|
||||
/* Clear the table, making it empty. */
|
||||
UNITTEST void Curl_uint_tbl_clear(struct uint_tbl *tbl);
|
||||
UNITTEST void Curl_uint32_tbl_clear(struct uint32_tbl *tbl);
|
||||
|
||||
void Curl_uint_tbl_init(struct uint_tbl *tbl,
|
||||
Curl_uint_tbl_entry_dtor *entry_dtor)
|
||||
void Curl_uint32_tbl_init(struct uint32_tbl *tbl,
|
||||
Curl_uint32_tbl_entry_dtor *entry_dtor)
|
||||
{
|
||||
memset(tbl, 0, sizeof(*tbl));
|
||||
tbl->entry_dtor = entry_dtor;
|
||||
tbl->last_key_added = UINT_MAX;
|
||||
tbl->last_key_added = UINT32_MAX;
|
||||
#ifdef DEBUGBUILD
|
||||
tbl->init = CURL_UINT_TBL_MAGIC;
|
||||
tbl->init = CURL_UINT32_TBL_MAGIC;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void uint_tbl_clear_rows(struct uint_tbl *tbl,
|
||||
unsigned int from,
|
||||
unsigned int upto_excluding)
|
||||
static void uint32_tbl_clear_rows(struct uint32_tbl *tbl,
|
||||
uint32_t from,
|
||||
uint32_t upto_excluding)
|
||||
{
|
||||
unsigned int i, end;
|
||||
uint32_t i, end;
|
||||
|
||||
end = CURLMIN(upto_excluding, tbl->nrows);
|
||||
for(i = from; i < end; ++i) {
|
||||
@@ -66,10 +66,10 @@ static void uint_tbl_clear_rows(struct uint_tbl *tbl,
|
||||
}
|
||||
|
||||
|
||||
CURLcode Curl_uint_tbl_resize(struct uint_tbl *tbl, unsigned int nrows)
|
||||
CURLcode Curl_uint32_tbl_resize(struct uint32_tbl *tbl, uint32_t nrows)
|
||||
{
|
||||
/* we use `tbl->nrows + 1` during iteration, want that to work */
|
||||
DEBUGASSERT(tbl->init == CURL_UINT_TBL_MAGIC);
|
||||
DEBUGASSERT(tbl->init == CURL_UINT32_TBL_MAGIC);
|
||||
if(!nrows)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
if(nrows != tbl->nrows) {
|
||||
@@ -79,7 +79,7 @@ CURLcode Curl_uint_tbl_resize(struct uint_tbl *tbl, unsigned int nrows)
|
||||
if(tbl->rows) {
|
||||
memcpy(rows, tbl->rows, (CURLMIN(nrows, tbl->nrows) * sizeof(void *)));
|
||||
if(nrows < tbl->nrows)
|
||||
uint_tbl_clear_rows(tbl, nrows, tbl->nrows);
|
||||
uint32_tbl_clear_rows(tbl, nrows, tbl->nrows);
|
||||
free(tbl->rows);
|
||||
}
|
||||
tbl->rows = rows;
|
||||
@@ -89,49 +89,49 @@ CURLcode Curl_uint_tbl_resize(struct uint_tbl *tbl, unsigned int nrows)
|
||||
}
|
||||
|
||||
|
||||
void Curl_uint_tbl_destroy(struct uint_tbl *tbl)
|
||||
void Curl_uint32_tbl_destroy(struct uint32_tbl *tbl)
|
||||
{
|
||||
DEBUGASSERT(tbl->init == CURL_UINT_TBL_MAGIC);
|
||||
Curl_uint_tbl_clear(tbl);
|
||||
DEBUGASSERT(tbl->init == CURL_UINT32_TBL_MAGIC);
|
||||
Curl_uint32_tbl_clear(tbl);
|
||||
free(tbl->rows);
|
||||
memset(tbl, 0, sizeof(*tbl));
|
||||
}
|
||||
|
||||
UNITTEST void Curl_uint_tbl_clear(struct uint_tbl *tbl)
|
||||
UNITTEST void Curl_uint32_tbl_clear(struct uint32_tbl *tbl)
|
||||
{
|
||||
DEBUGASSERT(tbl->init == CURL_UINT_TBL_MAGIC);
|
||||
uint_tbl_clear_rows(tbl, 0, tbl->nrows);
|
||||
DEBUGASSERT(tbl->init == CURL_UINT32_TBL_MAGIC);
|
||||
uint32_tbl_clear_rows(tbl, 0, tbl->nrows);
|
||||
DEBUGASSERT(!tbl->nentries);
|
||||
tbl->last_key_added = UINT_MAX;
|
||||
tbl->last_key_added = UINT32_MAX;
|
||||
}
|
||||
|
||||
|
||||
unsigned int Curl_uint_tbl_capacity(struct uint_tbl *tbl)
|
||||
uint32_t Curl_uint32_tbl_capacity(struct uint32_tbl *tbl)
|
||||
{
|
||||
return tbl->nrows;
|
||||
}
|
||||
|
||||
|
||||
unsigned int Curl_uint_tbl_count(struct uint_tbl *tbl)
|
||||
uint32_t Curl_uint32_tbl_count(struct uint32_tbl *tbl)
|
||||
{
|
||||
return tbl->nentries;
|
||||
}
|
||||
|
||||
|
||||
void *Curl_uint_tbl_get(struct uint_tbl *tbl, unsigned int key)
|
||||
void *Curl_uint32_tbl_get(struct uint32_tbl *tbl, uint32_t key)
|
||||
{
|
||||
return (key < tbl->nrows) ? tbl->rows[key] : NULL;
|
||||
}
|
||||
|
||||
|
||||
bool Curl_uint_tbl_add(struct uint_tbl *tbl, void *entry, unsigned int *pkey)
|
||||
bool Curl_uint32_tbl_add(struct uint32_tbl *tbl, void *entry, uint32_t *pkey)
|
||||
{
|
||||
unsigned int key, start_pos;
|
||||
uint32_t key, start_pos;
|
||||
|
||||
DEBUGASSERT(tbl->init == CURL_UINT_TBL_MAGIC);
|
||||
DEBUGASSERT(tbl->init == CURL_UINT32_TBL_MAGIC);
|
||||
if(!entry || !pkey)
|
||||
return FALSE;
|
||||
*pkey = UINT_MAX;
|
||||
*pkey = UINT32_MAX;
|
||||
if(tbl->nentries == tbl->nrows) /* full */
|
||||
return FALSE;
|
||||
|
||||
@@ -161,20 +161,20 @@ bool Curl_uint_tbl_add(struct uint_tbl *tbl, void *entry, unsigned int *pkey)
|
||||
}
|
||||
|
||||
|
||||
void Curl_uint_tbl_remove(struct uint_tbl *tbl, unsigned int key)
|
||||
void Curl_uint32_tbl_remove(struct uint32_tbl *tbl, uint32_t key)
|
||||
{
|
||||
uint_tbl_clear_rows(tbl, key, key + 1);
|
||||
uint32_tbl_clear_rows(tbl, key, key + 1);
|
||||
}
|
||||
|
||||
|
||||
bool Curl_uint_tbl_contains(struct uint_tbl *tbl, unsigned int key)
|
||||
bool Curl_uint32_tbl_contains(struct uint32_tbl *tbl, uint32_t key)
|
||||
{
|
||||
return (key < tbl->nrows) ? !!tbl->rows[key] : FALSE;
|
||||
}
|
||||
|
||||
|
||||
static bool uint_tbl_next_at(struct uint_tbl *tbl, unsigned int key,
|
||||
unsigned int *pkey, void **pentry)
|
||||
static bool uint32_tbl_next_at(struct uint32_tbl *tbl, uint32_t key,
|
||||
uint32_t *pkey, void **pentry)
|
||||
{
|
||||
for(; key < tbl->nrows; ++key) {
|
||||
if(tbl->rows[key]) {
|
||||
@@ -183,33 +183,33 @@ static bool uint_tbl_next_at(struct uint_tbl *tbl, unsigned int key,
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
*pkey = UINT_MAX; /* always invalid */
|
||||
*pkey = UINT32_MAX; /* always invalid */
|
||||
*pentry = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool Curl_uint_tbl_first(struct uint_tbl *tbl,
|
||||
unsigned int *pkey, void **pentry)
|
||||
bool Curl_uint32_tbl_first(struct uint32_tbl *tbl,
|
||||
uint32_t *pkey, void **pentry)
|
||||
{
|
||||
if(!pkey || !pentry)
|
||||
return FALSE;
|
||||
if(tbl->nentries && uint_tbl_next_at(tbl, 0, pkey, pentry))
|
||||
if(tbl->nentries && uint32_tbl_next_at(tbl, 0, pkey, pentry))
|
||||
return TRUE;
|
||||
DEBUGASSERT(!tbl->nentries);
|
||||
*pkey = UINT_MAX; /* always invalid */
|
||||
*pkey = UINT32_MAX; /* always invalid */
|
||||
*pentry = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
bool Curl_uint_tbl_next(struct uint_tbl *tbl, unsigned int last_key,
|
||||
unsigned int *pkey, void **pentry)
|
||||
bool Curl_uint32_tbl_next(struct uint32_tbl *tbl, uint32_t last_key,
|
||||
uint32_t *pkey, void **pentry)
|
||||
{
|
||||
if(!pkey || !pentry)
|
||||
return FALSE;
|
||||
if(uint_tbl_next_at(tbl, last_key + 1, pkey, pentry))
|
||||
if(uint32_tbl_next_at(tbl, last_key + 1, pkey, pentry))
|
||||
return TRUE;
|
||||
*pkey = UINT_MAX; /* always invalid */
|
||||
*pkey = UINT32_MAX; /* always invalid */
|
||||
*pentry = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -28,14 +28,14 @@
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* Destructor for a single table entry */
|
||||
typedef void Curl_uint_tbl_entry_dtor(unsigned int key, void *entry);
|
||||
typedef void Curl_uint32_tbl_entry_dtor(uint32_t key, void *entry);
|
||||
|
||||
struct uint_tbl {
|
||||
struct uint32_tbl {
|
||||
void **rows; /* array of void* holding entries */
|
||||
Curl_uint_tbl_entry_dtor *entry_dtor;
|
||||
unsigned int nrows; /* length of `rows` array */
|
||||
unsigned int nentries; /* entries in table */
|
||||
unsigned int last_key_added; /* UINT_MAX or last key added */
|
||||
Curl_uint32_tbl_entry_dtor *entry_dtor;
|
||||
uint32_t nrows; /* length of `rows` array */
|
||||
uint32_t nentries; /* entries in table */
|
||||
uint32_t last_key_added; /* UINT_MAX or last key added */
|
||||
#ifdef DEBUGBUILD
|
||||
int init;
|
||||
#endif
|
||||
@@ -44,42 +44,42 @@ struct uint_tbl {
|
||||
/* Initialize the table with 0 capacity.
|
||||
* The optional `entry_dtor` is called when a table entry is removed,
|
||||
* Passing NULL means no action is taken on removal. */
|
||||
void Curl_uint_tbl_init(struct uint_tbl *tbl,
|
||||
Curl_uint_tbl_entry_dtor *entry_dtor);
|
||||
void Curl_uint32_tbl_init(struct uint32_tbl *tbl,
|
||||
Curl_uint32_tbl_entry_dtor *entry_dtor);
|
||||
|
||||
/* Resize the table to change capacity `nmax`. When `nmax` is reduced,
|
||||
* all present entries with key equal or larger to `nmax` are removed. */
|
||||
CURLcode Curl_uint_tbl_resize(struct uint_tbl *tbl, unsigned int nmax);
|
||||
CURLcode Curl_uint32_tbl_resize(struct uint32_tbl *tbl, uint32_t nmax);
|
||||
|
||||
/* Destroy the table, freeing all entries. */
|
||||
void Curl_uint_tbl_destroy(struct uint_tbl *tbl);
|
||||
void Curl_uint32_tbl_destroy(struct uint32_tbl *tbl);
|
||||
|
||||
/* Get the table capacity. */
|
||||
unsigned int Curl_uint_tbl_capacity(struct uint_tbl *tbl);
|
||||
uint32_t Curl_uint32_tbl_capacity(struct uint32_tbl *tbl);
|
||||
|
||||
/* Get the number of entries in the table. */
|
||||
unsigned int Curl_uint_tbl_count(struct uint_tbl *tbl);
|
||||
uint32_t Curl_uint32_tbl_count(struct uint32_tbl *tbl);
|
||||
|
||||
/* Get the entry for key or NULL if not present */
|
||||
void *Curl_uint_tbl_get(struct uint_tbl *tbl, unsigned int key);
|
||||
void *Curl_uint32_tbl_get(struct uint32_tbl *tbl, uint32_t key);
|
||||
|
||||
/* Add a new entry to the table and assign it a free key.
|
||||
* Returns FALSE if the table is full.
|
||||
*
|
||||
* Keys are assigned in a round-robin manner.
|
||||
* No matter the capacity, UINT_MAX is never assigned. */
|
||||
bool Curl_uint_tbl_add(struct uint_tbl *tbl, void *entry, unsigned int *pkey);
|
||||
bool Curl_uint32_tbl_add(struct uint32_tbl *tbl, void *entry, uint32_t *pkey);
|
||||
|
||||
/* Remove the entry with `key`. */
|
||||
void Curl_uint_tbl_remove(struct uint_tbl *tbl, unsigned int key);
|
||||
void Curl_uint32_tbl_remove(struct uint32_tbl *tbl, uint32_t key);
|
||||
|
||||
/* Return TRUE if the table contains an tryn with that keys. */
|
||||
bool Curl_uint_tbl_contains(struct uint_tbl *tbl, unsigned int key);
|
||||
bool Curl_uint32_tbl_contains(struct uint32_tbl *tbl, uint32_t key);
|
||||
|
||||
/* Get the first entry in the table (with the smallest `key`).
|
||||
* Returns FALSE if the table is empty. */
|
||||
bool Curl_uint_tbl_first(struct uint_tbl *tbl,
|
||||
unsigned int *pkey, void **pentry);
|
||||
bool Curl_uint32_tbl_first(struct uint32_tbl *tbl,
|
||||
uint32_t *pkey, void **pentry);
|
||||
|
||||
/* Get the next key in the table, following `last_key` in natural order.
|
||||
* Put another way, this is the smallest key greater than `last_key` in
|
||||
@@ -92,7 +92,7 @@ bool Curl_uint_tbl_first(struct uint_tbl *tbl,
|
||||
* - added keys lower than 'last_key' will not show up.
|
||||
* - removed keys lower or equal to 'last_key' will not show up.
|
||||
* - removed keys higher than 'last_key' will not be visited. */
|
||||
bool Curl_uint_tbl_next(struct uint_tbl *tbl, unsigned int last_key,
|
||||
unsigned int *pkey, void **pentry);
|
||||
bool Curl_uint32_tbl_next(struct uint32_tbl *tbl, uint32_t last_key,
|
||||
uint32_t *pkey, void **pentry);
|
||||
|
||||
#endif /* HEADER_CURL_UINT_TABLE_H */
|
||||
|
||||
10
lib/url.c
10
lib/url.c
@@ -513,8 +513,8 @@ CURLcode Curl_open(struct Curl_easy **curl)
|
||||
data->state.recent_conn_id = -1;
|
||||
/* and not assigned an id yet */
|
||||
data->id = -1;
|
||||
data->mid = UINT_MAX;
|
||||
data->master_mid = UINT_MAX;
|
||||
data->mid = UINT32_MAX;
|
||||
data->master_mid = UINT32_MAX;
|
||||
data->progress.hide = TRUE;
|
||||
data->state.current_speed = -1; /* init to negative == impossible */
|
||||
|
||||
@@ -575,7 +575,7 @@ void Curl_conn_free(struct Curl_easy *data, struct connectdata *conn)
|
||||
Curl_safefree(conn->unix_domain_socket);
|
||||
#endif
|
||||
Curl_safefree(conn->destination);
|
||||
Curl_uint_spbset_destroy(&conn->xfers_attached);
|
||||
Curl_uint32_spbset_destroy(&conn->xfers_attached);
|
||||
Curl_hash_destroy(&conn->meta_hash);
|
||||
|
||||
free(conn); /* free all the connection oriented data */
|
||||
@@ -1407,7 +1407,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
|
||||
conn->transport_wanted = TRNSPRT_TCP; /* most of them are TCP streams */
|
||||
|
||||
/* Initialize the attached xfers bitset */
|
||||
Curl_uint_spbset_init(&conn->xfers_attached);
|
||||
Curl_uint32_spbset_init(&conn->xfers_attached);
|
||||
|
||||
/* Store the local bind parameters that will be used for this connection */
|
||||
if(data->set.str[STRING_DEVICE]) {
|
||||
@@ -3685,7 +3685,7 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||
connections_available = FALSE;
|
||||
break;
|
||||
case CPOOL_LIMIT_TOTAL:
|
||||
if(data->master_mid != UINT_MAX)
|
||||
if(data->master_mid != UINT32_MAX)
|
||||
CURL_TRC_M(data, "Allowing sub-requests (like DoH) to override "
|
||||
"max connection limit");
|
||||
else {
|
||||
|
||||
@@ -610,8 +610,8 @@ struct connectdata {
|
||||
handle is still used by one or more easy handles and can only used by any
|
||||
other easy handle without careful consideration (== only for
|
||||
multiplexing) and it cannot be used by another multi handle! */
|
||||
#define CONN_INUSE(c) (!Curl_uint_spbset_empty(&(c)->xfers_attached))
|
||||
#define CONN_ATTACHED(c) Curl_uint_spbset_count(&(c)->xfers_attached)
|
||||
#define CONN_INUSE(c) (!Curl_uint32_spbset_empty(&(c)->xfers_attached))
|
||||
#define CONN_ATTACHED(c) Curl_uint32_spbset_count(&(c)->xfers_attached)
|
||||
|
||||
/**** Fields set when inited and not modified again */
|
||||
curl_off_t connection_id; /* Contains a unique number to make it easier to
|
||||
@@ -671,7 +671,7 @@ struct connectdata {
|
||||
was used on this connection. */
|
||||
struct curltime keepalive;
|
||||
|
||||
struct uint_spbset xfers_attached; /* mids of attached transfers */
|
||||
struct uint32_spbset xfers_attached; /* mids of attached transfers */
|
||||
/* A connection cache from a SHARE might be used in several multi handles.
|
||||
* We MUST not reuse connections that are running in another multi,
|
||||
* for concurrency reasons. That multi might run in another thread.
|
||||
@@ -1631,8 +1631,8 @@ struct Curl_easy {
|
||||
/* once an easy handle is added to a multi, either explicitly by the
|
||||
* libcurl application or implicitly during `curl_easy_perform()`,
|
||||
* a unique identifier inside this one multi instance. */
|
||||
unsigned int mid;
|
||||
unsigned int master_mid; /* if set, this transfer belongs to a master */
|
||||
uint32_t mid;
|
||||
uint32_t master_mid; /* if set, this transfer belongs to a master */
|
||||
multi_sub_xfer_done_cb *sub_xfer_done;
|
||||
|
||||
struct connectdata *conn;
|
||||
|
||||
@@ -168,7 +168,7 @@ static void cf_ngtcp2_ctx_init(struct cf_ngtcp2_ctx *ctx)
|
||||
Curl_bufcp_init(&ctx->stream_bufcp, H3_STREAM_CHUNK_SIZE,
|
||||
H3_STREAM_POOL_SPARES);
|
||||
curlx_dyn_init(&ctx->scratch, CURL_MAX_HTTP_HEADER);
|
||||
Curl_uint_hash_init(&ctx->streams, 63, h3_stream_hash_free);
|
||||
Curl_uint32_hash_init(&ctx->streams, 63, h3_stream_hash_free);
|
||||
ctx->initialized = TRUE;
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ static void cf_ngtcp2_ctx_free(struct cf_ngtcp2_ctx *ctx)
|
||||
vquic_ctx_free(&ctx->q);
|
||||
Curl_bufcp_free(&ctx->stream_bufcp);
|
||||
curlx_dyn_free(&ctx->scratch);
|
||||
Curl_uint_hash_destroy(&ctx->streams);
|
||||
Curl_uint32_hash_destroy(&ctx->streams);
|
||||
Curl_ssl_peer_cleanup(&ctx->peer);
|
||||
}
|
||||
free(ctx);
|
||||
@@ -207,7 +207,7 @@ static void cf_ngtcp2_setup_keep_alive(struct Curl_cfilter *cf,
|
||||
ngtcp2_conn_set_keep_alive_timeout(ctx->qconn, UINT64_MAX);
|
||||
CURL_TRC_CF(data, cf, "no peer idle timeout, unset keep-alive");
|
||||
}
|
||||
else if(!Curl_uint_hash_count(&ctx->streams)) {
|
||||
else if(!Curl_uint32_hash_count(&ctx->streams)) {
|
||||
ngtcp2_conn_set_keep_alive_timeout(ctx->qconn, UINT64_MAX);
|
||||
CURL_TRC_CF(data, cf, "no active streams, unset keep-alive");
|
||||
}
|
||||
@@ -288,12 +288,12 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf,
|
||||
stream->sendbuf_len_in_flight = 0;
|
||||
Curl_h1_req_parse_init(&stream->h1, H1_PARSE_DEFAULT_MAX_LINE_LEN);
|
||||
|
||||
if(!Curl_uint_hash_set(&ctx->streams, data->mid, stream)) {
|
||||
if(!Curl_uint32_hash_set(&ctx->streams, data->mid, stream)) {
|
||||
h3_stream_ctx_free(stream);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(Curl_uint_hash_count(&ctx->streams) == 1)
|
||||
if(Curl_uint32_hash_count(&ctx->streams) == 1)
|
||||
cf_ngtcp2_setup_keep_alive(cf, data);
|
||||
|
||||
return CURLE_OK;
|
||||
@@ -303,10 +303,10 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf,
|
||||
struct cf_ngtcp2_sfind_ctx {
|
||||
int64_t stream_id;
|
||||
struct h3_stream_ctx *stream;
|
||||
unsigned int mid;
|
||||
uint32_t mid;
|
||||
};
|
||||
|
||||
static bool cf_ngtcp2_sfind(unsigned int mid, void *value, void *user_data)
|
||||
static bool cf_ngtcp2_sfind(uint32_t mid, void *value, void *user_data)
|
||||
{
|
||||
struct cf_ngtcp2_sfind_ctx *fctx = user_data;
|
||||
struct h3_stream_ctx *stream = value;
|
||||
@@ -325,7 +325,7 @@ cf_ngtcp2_get_stream(struct cf_ngtcp2_ctx *ctx, int64_t stream_id)
|
||||
struct cf_ngtcp2_sfind_ctx fctx;
|
||||
fctx.stream_id = stream_id;
|
||||
fctx.stream = NULL;
|
||||
Curl_uint_hash_visit(&ctx->streams, cf_ngtcp2_sfind, &fctx);
|
||||
Curl_uint32_hash_visit(&ctx->streams, cf_ngtcp2_sfind, &fctx);
|
||||
return fctx.stream;
|
||||
}
|
||||
#else
|
||||
@@ -374,8 +374,8 @@ static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
CURL_TRC_CF(data, cf, "[%" PRId64 "] easy handle is done",
|
||||
stream->id);
|
||||
cf_ngtcp2_stream_close(cf, data, stream);
|
||||
Curl_uint_hash_remove(&ctx->streams, data->mid);
|
||||
if(!Curl_uint_hash_count(&ctx->streams))
|
||||
Curl_uint32_hash_remove(&ctx->streams, data->mid);
|
||||
if(!Curl_uint32_hash_count(&ctx->streams))
|
||||
cf_ngtcp2_setup_keep_alive(cf, data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,7 +305,7 @@ static void cf_osslq_ctx_init(struct cf_osslq_ctx *ctx)
|
||||
DEBUGASSERT(!ctx->initialized);
|
||||
Curl_bufcp_init(&ctx->stream_bufcp, H3_STREAM_CHUNK_SIZE,
|
||||
H3_STREAM_POOL_SPARES);
|
||||
Curl_uint_hash_init(&ctx->streams, 63, h3_stream_hash_free);
|
||||
Curl_uint32_hash_init(&ctx->streams, 63, h3_stream_hash_free);
|
||||
ctx->poll_items = NULL;
|
||||
ctx->curl_items = NULL;
|
||||
ctx->items_max = 0;
|
||||
@@ -316,7 +316,7 @@ static void cf_osslq_ctx_free(struct cf_osslq_ctx *ctx)
|
||||
{
|
||||
if(ctx && ctx->initialized) {
|
||||
Curl_bufcp_free(&ctx->stream_bufcp);
|
||||
Curl_uint_hash_destroy(&ctx->streams);
|
||||
Curl_uint32_hash_destroy(&ctx->streams);
|
||||
Curl_ssl_peer_cleanup(&ctx->peer);
|
||||
free(ctx->poll_items);
|
||||
free(ctx->curl_items);
|
||||
@@ -634,7 +634,7 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf,
|
||||
stream->recv_buf_nonflow = 0;
|
||||
Curl_h1_req_parse_init(&stream->h1, H1_PARSE_DEFAULT_MAX_LINE_LEN);
|
||||
|
||||
if(!Curl_uint_hash_set(&ctx->streams, data->mid, stream)) {
|
||||
if(!Curl_uint32_hash_set(&ctx->streams, data->mid, stream)) {
|
||||
h3_stream_ctx_free(stream);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
@@ -659,7 +659,7 @@ static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
stream->closed = TRUE;
|
||||
}
|
||||
|
||||
Curl_uint_hash_remove(&ctx->streams, data->mid);
|
||||
Curl_uint32_hash_remove(&ctx->streams, data->mid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -668,7 +668,7 @@ struct cf_ossq_find_ctx {
|
||||
struct h3_stream_ctx *stream;
|
||||
};
|
||||
|
||||
static bool cf_osslq_find_stream(unsigned int mid, void *val, void *user_data)
|
||||
static bool cf_osslq_find_stream(uint32_t mid, void *val, void *user_data)
|
||||
{
|
||||
struct h3_stream_ctx *stream = val;
|
||||
struct cf_ossq_find_ctx *fctx = user_data;
|
||||
@@ -704,7 +704,7 @@ static struct cf_osslq_stream *cf_osslq_get_qstream(struct Curl_cfilter *cf,
|
||||
struct cf_ossq_find_ctx fctx;
|
||||
fctx.stream_id = stream_id;
|
||||
fctx.stream = NULL;
|
||||
Curl_uint_hash_visit(&ctx->streams, cf_osslq_find_stream, &fctx);
|
||||
Curl_uint32_hash_visit(&ctx->streams, cf_osslq_find_stream, &fctx);
|
||||
if(fctx.stream)
|
||||
return &fctx.stream->s;
|
||||
}
|
||||
@@ -1392,7 +1392,7 @@ struct cf_ossq_recv_ctx {
|
||||
CURLcode result;
|
||||
};
|
||||
|
||||
static bool cf_osslq_iter_recv(unsigned int mid, void *val, void *user_data)
|
||||
static bool cf_osslq_iter_recv(uint32_t mid, void *val, void *user_data)
|
||||
{
|
||||
struct h3_stream_ctx *stream = val;
|
||||
struct cf_ossq_recv_ctx *rctx = user_data;
|
||||
@@ -1455,7 +1455,7 @@ static CURLcode cf_progress_ingress(struct Curl_cfilter *cf,
|
||||
rctx.cf = cf;
|
||||
rctx.multi = data->multi;
|
||||
rctx.result = CURLE_OK;
|
||||
Curl_uint_hash_visit(&ctx->streams, cf_osslq_iter_recv, &rctx);
|
||||
Curl_uint32_hash_visit(&ctx->streams, cf_osslq_iter_recv, &rctx);
|
||||
result = rctx.result;
|
||||
}
|
||||
|
||||
@@ -1470,7 +1470,7 @@ struct cf_ossq_fill_ctx {
|
||||
size_t n;
|
||||
};
|
||||
|
||||
static bool cf_osslq_collect_block_send(unsigned int mid, void *val,
|
||||
static bool cf_osslq_collect_block_send(uint32_t mid, void *val,
|
||||
void *user_data)
|
||||
{
|
||||
struct h3_stream_ctx *stream = val;
|
||||
@@ -1508,8 +1508,8 @@ static CURLcode cf_osslq_check_and_unblock(struct Curl_cfilter *cf,
|
||||
if(ctx->h3.conn) {
|
||||
struct cf_ossq_fill_ctx fill_ctx;
|
||||
|
||||
if(ctx->items_max < Curl_uint_hash_count(&ctx->streams)) {
|
||||
size_t nmax = Curl_uint_hash_count(&ctx->streams);
|
||||
if(ctx->items_max < Curl_uint32_hash_count(&ctx->streams)) {
|
||||
size_t nmax = Curl_uint32_hash_count(&ctx->streams);
|
||||
ctx->items_max = 0;
|
||||
tmpptr = realloc(ctx->poll_items, nmax * sizeof(SSL_POLL_ITEM));
|
||||
if(!tmpptr) {
|
||||
@@ -1534,7 +1534,7 @@ static CURLcode cf_osslq_check_and_unblock(struct Curl_cfilter *cf,
|
||||
fill_ctx.ctx = ctx;
|
||||
fill_ctx.multi = data->multi;
|
||||
fill_ctx.n = 0;
|
||||
Curl_uint_hash_visit(&ctx->streams, cf_osslq_collect_block_send,
|
||||
Curl_uint32_hash_visit(&ctx->streams, cf_osslq_collect_block_send,
|
||||
&fill_ctx);
|
||||
poll_count = fill_ctx.n;
|
||||
if(poll_count) {
|
||||
|
||||
@@ -125,7 +125,7 @@ static void cf_quiche_ctx_init(struct cf_quiche_ctx *ctx)
|
||||
#endif
|
||||
Curl_bufcp_init(&ctx->stream_bufcp, H3_STREAM_CHUNK_SIZE,
|
||||
H3_STREAM_POOL_SPARES);
|
||||
Curl_uint_hash_init(&ctx->streams, 63, h3_stream_hash_free);
|
||||
Curl_uint32_hash_init(&ctx->streams, 63, h3_stream_hash_free);
|
||||
ctx->data_recvd = 0;
|
||||
ctx->initialized = TRUE;
|
||||
}
|
||||
@@ -139,7 +139,7 @@ static void cf_quiche_ctx_free(struct cf_quiche_ctx *ctx)
|
||||
Curl_ssl_peer_cleanup(&ctx->peer);
|
||||
vquic_ctx_free(&ctx->q);
|
||||
Curl_bufcp_free(&ctx->stream_bufcp);
|
||||
Curl_uint_hash_destroy(&ctx->streams);
|
||||
Curl_uint32_hash_destroy(&ctx->streams);
|
||||
}
|
||||
free(ctx);
|
||||
}
|
||||
@@ -210,7 +210,7 @@ struct cf_quiche_visit_ctx {
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
static bool cf_quiche_stream_do(unsigned int mid, void *val, void *user_data)
|
||||
static bool cf_quiche_stream_do(uint32_t mid, void *val, void *user_data)
|
||||
{
|
||||
struct cf_quiche_visit_ctx *vctx = user_data;
|
||||
struct h3_stream_ctx *stream = val;
|
||||
@@ -231,7 +231,7 @@ static void cf_quiche_for_all_streams(struct Curl_cfilter *cf,
|
||||
vctx.multi = multi;
|
||||
vctx.cb = do_cb;
|
||||
vctx.user_data = user_data;
|
||||
Curl_uint_hash_visit(&ctx->streams, cf_quiche_stream_do, &vctx);
|
||||
Curl_uint32_hash_visit(&ctx->streams, cf_quiche_stream_do, &vctx);
|
||||
}
|
||||
|
||||
static bool cf_quiche_do_resume(struct Curl_cfilter *cf,
|
||||
@@ -278,7 +278,7 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf,
|
||||
H3_STREAM_RECV_CHUNKS, BUFQ_OPT_SOFT_LIMIT);
|
||||
Curl_h1_req_parse_init(&stream->h1, H1_PARSE_DEFAULT_MAX_LINE_LEN);
|
||||
|
||||
if(!Curl_uint_hash_set(&ctx->streams, data->mid, stream)) {
|
||||
if(!Curl_uint32_hash_set(&ctx->streams, data->mid, stream)) {
|
||||
h3_stream_ctx_free(stream);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
@@ -308,7 +308,7 @@ static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
if(result)
|
||||
CURL_TRC_CF(data, cf, "data_done, flush egress -> %d", result);
|
||||
}
|
||||
Curl_uint_hash_remove(&ctx->streams, data->mid);
|
||||
Curl_uint32_hash_remove(&ctx->streams, data->mid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -558,7 +558,7 @@ struct cf_quich_disp_ctx {
|
||||
CURLcode result;
|
||||
};
|
||||
|
||||
static bool cf_quiche_disp_event(unsigned int mid, void *val, void *user_data)
|
||||
static bool cf_quiche_disp_event(uint32_t mid, void *val, void *user_data)
|
||||
{
|
||||
struct cf_quich_disp_ctx *dctx = user_data;
|
||||
struct h3_stream_ctx *stream = val;
|
||||
@@ -607,7 +607,7 @@ static CURLcode cf_poll_events(struct Curl_cfilter *cf,
|
||||
else {
|
||||
/* another transfer, do not return errors, as they are not for
|
||||
* the calling transfer */
|
||||
Curl_uint_hash_visit(&ctx->streams, cf_quiche_disp_event, &dctx);
|
||||
Curl_uint32_hash_visit(&ctx->streams, cf_quiche_disp_event, &dctx);
|
||||
quiche_h3_event_free(ev);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ struct cf_quic_ctx {
|
||||
};
|
||||
|
||||
#define H3_STREAM_CTX(ctx,data) \
|
||||
(data ? Curl_uint_hash_get(&(ctx)->streams, (data)->mid) : NULL)
|
||||
(data ? Curl_uint32_hash_get(&(ctx)->streams, (data)->mid) : NULL)
|
||||
|
||||
CURLcode vquic_ctx_init(struct cf_quic_ctx *qctx);
|
||||
void vquic_ctx_free(struct cf_quic_ctx *qctx);
|
||||
|
||||
@@ -36,13 +36,13 @@ static void t1616_mydtor(unsigned int id, void *elem)
|
||||
|
||||
static CURLcode t1616_setup(struct uint_hash *hash)
|
||||
{
|
||||
Curl_uint_hash_init(hash, 15, t1616_mydtor);
|
||||
Curl_uint32_hash_init(hash, 15, t1616_mydtor);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void t1616_stop(struct uint_hash *hash)
|
||||
{
|
||||
Curl_uint_hash_destroy(hash);
|
||||
Curl_uint32_hash_destroy(hash);
|
||||
}
|
||||
|
||||
static CURLcode test_unit1616(const char *arg)
|
||||
@@ -61,27 +61,27 @@ static CURLcode test_unit1616(const char *arg)
|
||||
value = malloc(sizeof(int));
|
||||
abort_unless(value != NULL, "Out of memory");
|
||||
*value = 199;
|
||||
ok = Curl_uint_hash_set(&hash, key, value);
|
||||
ok = Curl_uint32_hash_set(&hash, key, value);
|
||||
if(!ok)
|
||||
free(value);
|
||||
abort_unless(ok, "insertion into hash failed");
|
||||
v = Curl_uint_hash_get(&hash, key);
|
||||
v = Curl_uint32_hash_get(&hash, key);
|
||||
abort_unless(v == value, "lookup present entry failed");
|
||||
v = Curl_uint_hash_get(&hash, key2);
|
||||
v = Curl_uint32_hash_get(&hash, key2);
|
||||
abort_unless(!v, "lookup missing entry failed");
|
||||
Curl_uint_hash_clear(&hash);
|
||||
Curl_uint32_hash_clear(&hash);
|
||||
|
||||
/* Attempt to add another key/value pair */
|
||||
value2 = malloc(sizeof(int));
|
||||
abort_unless(value2 != NULL, "Out of memory");
|
||||
*value2 = 204;
|
||||
ok = Curl_uint_hash_set(&hash, key2, value2);
|
||||
ok = Curl_uint32_hash_set(&hash, key2, value2);
|
||||
if(!ok)
|
||||
free(value2);
|
||||
abort_unless(ok, "insertion into hash failed");
|
||||
v = Curl_uint_hash_get(&hash, key2);
|
||||
v = Curl_uint32_hash_get(&hash, key2);
|
||||
abort_unless(v == value2, "lookup present entry failed");
|
||||
v = Curl_uint_hash_get(&hash, key);
|
||||
v = Curl_uint32_hash_get(&hash, key);
|
||||
abort_unless(!v, "lookup missing entry failed");
|
||||
|
||||
UNITTEST_END(t1616_stop(&hash))
|
||||
|
||||
@@ -30,36 +30,38 @@
|
||||
static void check_set(const char *name, unsigned int capacity,
|
||||
const unsigned int *s, size_t slen)
|
||||
{
|
||||
struct uint_bset bset;
|
||||
struct uint32_bset bset;
|
||||
size_t i, j;
|
||||
unsigned int n, c;
|
||||
|
||||
curl_mfprintf(stderr, "test %s, capacity=%u, %zu numbers\n",
|
||||
name, capacity, slen);
|
||||
Curl_uint_bset_init(&bset);
|
||||
fail_unless(!Curl_uint_bset_resize(&bset, capacity), "bset resize failed");
|
||||
c = Curl_uint_bset_capacity(&bset);
|
||||
Curl_uint32_bset_init(&bset);
|
||||
fail_unless(!Curl_uint32_bset_resize(&bset, capacity), "bset resize failed");
|
||||
c = Curl_uint32_bset_capacity(&bset);
|
||||
fail_unless(c == (((capacity + 63) / 64) * 64), "wrong capacity");
|
||||
|
||||
Curl_uint_bset_clear(&bset);
|
||||
c = Curl_uint_bset_count(&bset);
|
||||
Curl_uint32_bset_clear(&bset);
|
||||
c = Curl_uint32_bset_count(&bset);
|
||||
fail_unless(c == 0, "set count is not 0");
|
||||
|
||||
for(i = 0; i < slen; ++i) { /* add all */
|
||||
fail_unless(Curl_uint_bset_add(&bset, s[i]), "failed to add");
|
||||
fail_unless(Curl_uint32_bset_add(&bset, s[i]), "failed to add");
|
||||
for(j = i + 1; j < slen; ++j)
|
||||
fail_unless(!Curl_uint_bset_contains(&bset, s[j]), "unexpectedly found");
|
||||
fail_unless(!Curl_uint32_bset_contains(&bset, s[j]),
|
||||
"unexpectedly found");
|
||||
}
|
||||
|
||||
for(i = 0; i < slen; ++i) { /* all present */
|
||||
fail_unless(Curl_uint_bset_contains(&bset, s[i]), "failed presence check");
|
||||
fail_unless(Curl_uint32_bset_contains(&bset, s[i]),
|
||||
"failed presence check");
|
||||
}
|
||||
|
||||
/* iterator over all numbers */
|
||||
fail_unless(Curl_uint_bset_first(&bset, &n), "first failed");
|
||||
fail_unless(Curl_uint32_bset_first(&bset, &n), "first failed");
|
||||
fail_unless(n == s[0], "first not correct number");
|
||||
for(i = 1; i < slen; ++i) {
|
||||
fail_unless(Curl_uint_bset_next(&bset, n, &n), "next failed");
|
||||
fail_unless(Curl_uint32_bset_next(&bset, n, &n), "next failed");
|
||||
if(n != s[i]) {
|
||||
curl_mfprintf(stderr, "expected next to be %u, not %u\n", s[i], n);
|
||||
fail_unless(n == s[i], "next not correct number");
|
||||
@@ -67,57 +69,58 @@ static void check_set(const char *name, unsigned int capacity,
|
||||
}
|
||||
|
||||
/* Adding capacity number does not work (0 - capacity-1) */
|
||||
c = Curl_uint_bset_capacity(&bset);
|
||||
fail_unless(!Curl_uint_bset_add(&bset, c), "add out of range worked");
|
||||
c = Curl_uint32_bset_capacity(&bset);
|
||||
fail_unless(!Curl_uint32_bset_add(&bset, c), "add out of range worked");
|
||||
/* The count it correct */
|
||||
c = Curl_uint_bset_count(&bset);
|
||||
c = Curl_uint32_bset_count(&bset);
|
||||
fail_unless(c == slen, "set count is wrong");
|
||||
|
||||
for(i = 0; i < slen; i += 2) { /* remove every 2nd */
|
||||
Curl_uint_bset_remove(&bset, s[i]);
|
||||
fail_unless(!Curl_uint_bset_contains(&bset, s[i]), "unexpectedly found");
|
||||
Curl_uint32_bset_remove(&bset, s[i]);
|
||||
fail_unless(!Curl_uint32_bset_contains(&bset, s[i]), "unexpectedly found");
|
||||
}
|
||||
for(i = 1; i < slen; i += 2) { /* others still there */
|
||||
fail_unless(Curl_uint_bset_contains(&bset, s[i]), "unexpectedly gone");
|
||||
fail_unless(Curl_uint32_bset_contains(&bset, s[i]), "unexpectedly gone");
|
||||
}
|
||||
/* The count is half */
|
||||
c = Curl_uint_bset_count(&bset);
|
||||
c = Curl_uint32_bset_count(&bset);
|
||||
fail_unless(c == slen/2, "set count is wrong");
|
||||
|
||||
Curl_uint_bset_clear(&bset);
|
||||
c = Curl_uint_bset_count(&bset);
|
||||
Curl_uint32_bset_clear(&bset);
|
||||
c = Curl_uint32_bset_count(&bset);
|
||||
fail_unless(c == 0, "set count is not 0");
|
||||
for(i = 0; i < slen; i++) { /* none present any longer */
|
||||
fail_unless(!Curl_uint_bset_contains(&bset, s[i]), "unexpectedly there");
|
||||
fail_unless(!Curl_uint32_bset_contains(&bset, s[i]), "unexpectedly there");
|
||||
}
|
||||
|
||||
for(i = 0; i < slen; ++i) { /* add all again */
|
||||
fail_unless(Curl_uint_bset_add(&bset, s[i]), "failed to add");
|
||||
fail_unless(Curl_uint32_bset_add(&bset, s[i]), "failed to add");
|
||||
}
|
||||
|
||||
fail_unless(!Curl_uint_bset_resize(&bset, capacity * 2),
|
||||
fail_unless(!Curl_uint32_bset_resize(&bset, capacity * 2),
|
||||
"resize double failed");
|
||||
for(i = 0; i < slen; i++) { /* all still present after resize */
|
||||
fail_unless(Curl_uint_bset_contains(&bset, s[i]), "unexpectedly lost");
|
||||
fail_unless(Curl_uint32_bset_contains(&bset, s[i]), "unexpectedly lost");
|
||||
}
|
||||
|
||||
fail_unless(!Curl_uint_bset_resize(&bset, capacity), "resize back failed");
|
||||
fail_unless(!Curl_uint32_bset_resize(&bset, capacity), "resize back failed");
|
||||
for(i = 0; i < slen; i++) /* all still present after resize back */
|
||||
fail_unless(Curl_uint_bset_contains(&bset, s[i]), "unexpectedly lost");
|
||||
fail_unless(Curl_uint32_bset_contains(&bset, s[i]), "unexpectedly lost");
|
||||
|
||||
fail_unless(!Curl_uint_bset_resize(&bset, capacity/2), "resize half failed");
|
||||
fail_unless(!Curl_uint32_bset_resize(&bset, capacity/2),
|
||||
"resize half failed");
|
||||
/* halved the size, what numbers remain in set? */
|
||||
c = Curl_uint_bset_capacity(&bset);
|
||||
c = Curl_uint32_bset_capacity(&bset);
|
||||
n = 0;
|
||||
for(i = 0; i < slen; ++i) {
|
||||
if(s[i] < c)
|
||||
++n;
|
||||
}
|
||||
fail_unless(n == Curl_uint_bset_count(&bset), "set count(halved) wrong");
|
||||
fail_unless(n == Curl_uint32_bset_count(&bset), "set count(halved) wrong");
|
||||
for(i = 0; i < n; i++) /* still present after resize half */
|
||||
fail_unless(Curl_uint_bset_contains(&bset, s[i]), "unexpectedly lost");
|
||||
fail_unless(Curl_uint32_bset_contains(&bset, s[i]), "unexpectedly lost");
|
||||
|
||||
Curl_uint_bset_destroy(&bset);
|
||||
Curl_uint32_bset_destroy(&bset);
|
||||
}
|
||||
|
||||
static CURLcode test_unit3211(const char *arg)
|
||||
|
||||
@@ -30,20 +30,20 @@
|
||||
|
||||
#define TBL_SIZE 100
|
||||
|
||||
static CURLcode t3212_setup(struct uint_tbl *tbl)
|
||||
static CURLcode t3212_setup(struct uint32_tbl *tbl)
|
||||
{
|
||||
Curl_uint_tbl_init(tbl, NULL);
|
||||
return Curl_uint_tbl_resize(tbl, TBL_SIZE);
|
||||
Curl_uint32_tbl_init(tbl, NULL);
|
||||
return Curl_uint32_tbl_resize(tbl, TBL_SIZE);
|
||||
}
|
||||
|
||||
static void t3212_stop(struct uint_tbl *tbl)
|
||||
static void t3212_stop(struct uint32_tbl *tbl)
|
||||
{
|
||||
Curl_uint_tbl_destroy(tbl);
|
||||
Curl_uint32_tbl_destroy(tbl);
|
||||
}
|
||||
|
||||
static CURLcode test_unit3212(const char *arg)
|
||||
{
|
||||
struct uint_tbl tbl;
|
||||
struct uint32_tbl tbl;
|
||||
int dummy;
|
||||
|
||||
UNITTEST_BEGIN(t3212_setup(&tbl))
|
||||
@@ -51,83 +51,85 @@ static CURLcode test_unit3212(const char *arg)
|
||||
unsigned int i, key, n;
|
||||
void *entry;
|
||||
|
||||
fail_unless(Curl_uint_tbl_capacity(&tbl) == TBL_SIZE, "wrong capacity");
|
||||
fail_unless(Curl_uint32_tbl_capacity(&tbl) == TBL_SIZE, "wrong capacity");
|
||||
|
||||
for(i = 0; i < TBL_SIZE; ++i) {
|
||||
fail_unless(Curl_uint_tbl_add(&tbl, &dummy, &key), "failed to add");
|
||||
fail_unless(Curl_uint32_tbl_add(&tbl, &dummy, &key), "failed to add");
|
||||
fail_unless(key == i, "unexpected key assigned");
|
||||
}
|
||||
/* table should be full now */
|
||||
fail_unless(Curl_uint_tbl_count(&tbl) == TBL_SIZE, "wrong count");
|
||||
fail_unless(!Curl_uint_tbl_add(&tbl, &dummy, &key), "could add more");
|
||||
fail_unless(Curl_uint32_tbl_count(&tbl) == TBL_SIZE, "wrong count");
|
||||
fail_unless(!Curl_uint32_tbl_add(&tbl, &dummy, &key), "could add more");
|
||||
/* remove every 2nd entry, from full table */
|
||||
n = TBL_SIZE;
|
||||
for(i = 0; i < TBL_SIZE; i += 2) {
|
||||
Curl_uint_tbl_remove(&tbl, i);
|
||||
Curl_uint32_tbl_remove(&tbl, i);
|
||||
--n;
|
||||
fail_unless(Curl_uint_tbl_count(&tbl) == n, "wrong count after remove");
|
||||
fail_unless(Curl_uint32_tbl_count(&tbl) == n, "wrong count after remove");
|
||||
}
|
||||
/* remove same again, should not change count */
|
||||
for(i = 0; i < TBL_SIZE; i += 2) {
|
||||
Curl_uint_tbl_remove(&tbl, i);
|
||||
fail_unless(Curl_uint_tbl_count(&tbl) == n, "wrong count after remove");
|
||||
Curl_uint32_tbl_remove(&tbl, i);
|
||||
fail_unless(Curl_uint32_tbl_count(&tbl) == n, "wrong count after remove");
|
||||
}
|
||||
/* still contains all odd entries */
|
||||
for(i = 1; i < TBL_SIZE; i += 2) {
|
||||
fail_unless(Curl_uint_tbl_contains(&tbl, i), "does not contain");
|
||||
fail_unless(Curl_uint_tbl_get(&tbl, i) == &dummy,
|
||||
fail_unless(Curl_uint32_tbl_contains(&tbl, i), "does not contain");
|
||||
fail_unless(Curl_uint32_tbl_get(&tbl, i) == &dummy,
|
||||
"does not contain dummy");
|
||||
}
|
||||
/* get the first key */
|
||||
fail_unless(Curl_uint_tbl_first(&tbl, &key, &entry), "first failed");
|
||||
fail_unless(Curl_uint32_tbl_first(&tbl, &key, &entry), "first failed");
|
||||
fail_unless(key == 1, "unexpected first key");
|
||||
fail_unless(entry == &dummy, "unexpected first entry");
|
||||
/* get the second key */
|
||||
fail_unless(Curl_uint_tbl_next(&tbl, 1, &key, &entry), "next1 failed");
|
||||
fail_unless(Curl_uint32_tbl_next(&tbl, 1, &key, &entry), "next1 failed");
|
||||
fail_unless(key == 3, "unexpected second key");
|
||||
fail_unless(entry == &dummy, "unexpected second entry");
|
||||
/* get the key after 42 */
|
||||
fail_unless(Curl_uint_tbl_next(&tbl, 42, &key, &entry), "next42 failed");
|
||||
fail_unless(Curl_uint32_tbl_next(&tbl, 42, &key, &entry), "next42 failed");
|
||||
fail_unless(key == 43, "unexpected next42 key");
|
||||
fail_unless(entry == &dummy, "unexpected next42 entry");
|
||||
|
||||
/* double capacity */
|
||||
n = Curl_uint_tbl_count(&tbl);
|
||||
fail_unless(!Curl_uint_tbl_resize(&tbl, TBL_SIZE * 2),
|
||||
n = Curl_uint32_tbl_count(&tbl);
|
||||
fail_unless(!Curl_uint32_tbl_resize(&tbl, TBL_SIZE * 2),
|
||||
"error doubling size");
|
||||
fail_unless(Curl_uint_tbl_count(&tbl) == n, "wrong resize count");
|
||||
fail_unless(Curl_uint32_tbl_count(&tbl) == n, "wrong resize count");
|
||||
/* resize to half of original */
|
||||
fail_unless(!Curl_uint_tbl_resize(&tbl, TBL_SIZE / 2), "error halving size");
|
||||
fail_unless(Curl_uint_tbl_count(&tbl) == n / 2, "wrong half size count");
|
||||
fail_unless(!Curl_uint32_tbl_resize(&tbl, TBL_SIZE / 2),
|
||||
"error halving size");
|
||||
fail_unless(Curl_uint32_tbl_count(&tbl) == n / 2, "wrong half size count");
|
||||
for(i = 1; i < TBL_SIZE / 2; i += 2) {
|
||||
fail_unless(Curl_uint_tbl_contains(&tbl, i), "does not contain");
|
||||
fail_unless(Curl_uint_tbl_get(&tbl, i) == &dummy,
|
||||
fail_unless(Curl_uint32_tbl_contains(&tbl, i), "does not contain");
|
||||
fail_unless(Curl_uint32_tbl_get(&tbl, i) == &dummy,
|
||||
"does not contain dummy");
|
||||
}
|
||||
/* clear */
|
||||
Curl_uint_tbl_clear(&tbl);
|
||||
fail_unless(!Curl_uint_tbl_count(&tbl), "count not 0 after clear");
|
||||
Curl_uint32_tbl_clear(&tbl);
|
||||
fail_unless(!Curl_uint32_tbl_count(&tbl), "count not 0 after clear");
|
||||
for(i = 0; i < TBL_SIZE / 2; ++i) {
|
||||
fail_unless(!Curl_uint_tbl_contains(&tbl, i), "does contain, should not");
|
||||
fail_unless(!Curl_uint32_tbl_contains(&tbl, i),
|
||||
"does contain, should not");
|
||||
}
|
||||
/* add after clear gets key 0 again */
|
||||
fail_unless(Curl_uint_tbl_add(&tbl, &dummy, &key), "failed to add");
|
||||
fail_unless(Curl_uint32_tbl_add(&tbl, &dummy, &key), "failed to add");
|
||||
fail_unless(key == 0, "unexpected key assigned");
|
||||
/* remove it again and add, should get key 1 */
|
||||
Curl_uint_tbl_remove(&tbl, key);
|
||||
fail_unless(Curl_uint_tbl_add(&tbl, &dummy, &key), "failed to add");
|
||||
Curl_uint32_tbl_remove(&tbl, key);
|
||||
fail_unless(Curl_uint32_tbl_add(&tbl, &dummy, &key), "failed to add");
|
||||
fail_unless(key == 1, "unexpected key assigned");
|
||||
/* clear, fill, remove one, add, should get the removed key again */
|
||||
Curl_uint_tbl_clear(&tbl);
|
||||
for(i = 0; i < Curl_uint_tbl_capacity(&tbl); ++i)
|
||||
fail_unless(Curl_uint_tbl_add(&tbl, &dummy, &key), "failed to add");
|
||||
fail_unless(!Curl_uint_tbl_add(&tbl, &dummy, &key), "add on full");
|
||||
Curl_uint_tbl_remove(&tbl, 17);
|
||||
fail_unless(Curl_uint_tbl_add(&tbl, &dummy, &key), "failed to add again");
|
||||
Curl_uint32_tbl_clear(&tbl);
|
||||
for(i = 0; i < Curl_uint32_tbl_capacity(&tbl); ++i)
|
||||
fail_unless(Curl_uint32_tbl_add(&tbl, &dummy, &key), "failed to add");
|
||||
fail_unless(!Curl_uint32_tbl_add(&tbl, &dummy, &key), "add on full");
|
||||
Curl_uint32_tbl_remove(&tbl, 17);
|
||||
fail_unless(Curl_uint32_tbl_add(&tbl, &dummy, &key), "failed to add again");
|
||||
fail_unless(key == 17, "unexpected key assigned");
|
||||
/* and again, triggering key search wrap around */
|
||||
Curl_uint_tbl_remove(&tbl, 17);
|
||||
fail_unless(Curl_uint_tbl_add(&tbl, &dummy, &key), "failed to add again");
|
||||
Curl_uint32_tbl_remove(&tbl, 17);
|
||||
fail_unless(Curl_uint32_tbl_add(&tbl, &dummy, &key), "failed to add again");
|
||||
fail_unless(key == 17, "unexpected key assigned");
|
||||
|
||||
UNITTEST_END(t3212_stop(&tbl))
|
||||
|
||||
@@ -30,35 +30,35 @@
|
||||
|
||||
static void check_spbset(const char *name, const unsigned int *s, size_t slen)
|
||||
{
|
||||
struct uint_spbset bset;
|
||||
struct uint32_spbset bset;
|
||||
size_t i, j;
|
||||
unsigned int n, c;
|
||||
|
||||
curl_mfprintf(stderr, "test %s, %zu numbers\n", name, slen);
|
||||
|
||||
Curl_uint_spbset_init(&bset);
|
||||
Curl_uint32_spbset_init(&bset);
|
||||
|
||||
Curl_uint_spbset_clear(&bset);
|
||||
c = Curl_uint_spbset_count(&bset);
|
||||
Curl_uint32_spbset_clear(&bset);
|
||||
c = Curl_uint32_spbset_count(&bset);
|
||||
fail_unless(c == 0, "set count is not 0");
|
||||
|
||||
for(i = 0; i < slen; ++i) { /* add all */
|
||||
fail_unless(Curl_uint_spbset_add(&bset, s[i]), "failed to add");
|
||||
fail_unless(Curl_uint32_spbset_add(&bset, s[i]), "failed to add");
|
||||
for(j = i + 1; j < slen; ++j)
|
||||
fail_unless(!Curl_uint_spbset_contains(&bset, s[j]),
|
||||
fail_unless(!Curl_uint32_spbset_contains(&bset, s[j]),
|
||||
"unexpectedly found");
|
||||
}
|
||||
|
||||
for(i = 0; i < slen; ++i) { /* all present */
|
||||
fail_unless(Curl_uint_spbset_contains(&bset, s[i]),
|
||||
fail_unless(Curl_uint32_spbset_contains(&bset, s[i]),
|
||||
"failed presence check");
|
||||
}
|
||||
|
||||
/* iterator over all numbers */
|
||||
fail_unless(Curl_uint_spbset_first(&bset, &n), "first failed");
|
||||
fail_unless(Curl_uint32_spbset_first(&bset, &n), "first failed");
|
||||
fail_unless(n == s[0], "first not correct number");
|
||||
for(i = 1; i < slen; ++i) {
|
||||
fail_unless(Curl_uint_spbset_next(&bset, n, &n), "next failed");
|
||||
fail_unless(Curl_uint32_spbset_next(&bset, n, &n), "next failed");
|
||||
if(n != s[i]) {
|
||||
curl_mfprintf(stderr, "expected next to be %u, not %u\n", s[i], n);
|
||||
fail_unless(n == s[i], "next not correct number");
|
||||
@@ -66,28 +66,30 @@ static void check_spbset(const char *name, const unsigned int *s, size_t slen)
|
||||
}
|
||||
|
||||
for(i = 0; i < slen; i += 2) { /* remove every 2nd */
|
||||
Curl_uint_spbset_remove(&bset, s[i]);
|
||||
fail_unless(!Curl_uint_spbset_contains(&bset, s[i]), "unexpectedly found");
|
||||
Curl_uint32_spbset_remove(&bset, s[i]);
|
||||
fail_unless(!Curl_uint32_spbset_contains(&bset, s[i]),
|
||||
"unexpectedly found");
|
||||
}
|
||||
for(i = 1; i < slen; i += 2) { /* others still there */
|
||||
fail_unless(Curl_uint_spbset_contains(&bset, s[i]), "unexpectedly gone");
|
||||
fail_unless(Curl_uint32_spbset_contains(&bset, s[i]), "unexpectedly gone");
|
||||
}
|
||||
/* The count is half */
|
||||
c = Curl_uint_spbset_count(&bset);
|
||||
c = Curl_uint32_spbset_count(&bset);
|
||||
fail_unless(c == slen/2, "set count is wrong");
|
||||
|
||||
Curl_uint_spbset_clear(&bset);
|
||||
c = Curl_uint_spbset_count(&bset);
|
||||
Curl_uint32_spbset_clear(&bset);
|
||||
c = Curl_uint32_spbset_count(&bset);
|
||||
fail_unless(c == 0, "set count is not 0");
|
||||
for(i = 0; i < slen; i++) { /* none present any longer */
|
||||
fail_unless(!Curl_uint_spbset_contains(&bset, s[i]), "unexpectedly there");
|
||||
fail_unless(!Curl_uint32_spbset_contains(&bset, s[i]),
|
||||
"unexpectedly there");
|
||||
}
|
||||
|
||||
for(i = 0; i < slen; ++i) { /* add all again */
|
||||
fail_unless(Curl_uint_spbset_add(&bset, s[i]), "failed to add");
|
||||
fail_unless(Curl_uint32_spbset_add(&bset, s[i]), "failed to add");
|
||||
}
|
||||
|
||||
Curl_uint_spbset_destroy(&bset);
|
||||
Curl_uint32_spbset_destroy(&bset);
|
||||
}
|
||||
|
||||
static CURLcode test_unit3213(const char *arg)
|
||||
|
||||
Reference in New Issue
Block a user