multi: initialisation order

When creating a multi handle, global_init() may not have been
invoked that. There is a lazy check for this in easy_init()
that trigger global_init().

Create the admin handle for a multi first, before any further
operations, so easy_init() can trigger a global_init() when
necessary.

Closes #22606
This commit is contained in:
Stefan Eissing 2026-08-17 14:18:50 +02:00 committed by Daniel Stenberg
parent 5406d2627c
commit 8e2eced234
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2

View file

@ -235,8 +235,23 @@ struct Curl_multi *Curl_multi_handle(uint32_t xfer_table_size,
multi->magic = CURLMULTI_MAGIC_NUMBER;
/* Initialisation order is important here!
* easy_init() does a lazy check on curl_global_init() which sets
* up platform specific things we need. For example calling curlx_pnow()
* before this is not safe. */
multi->admin = curl_easy_init();
if(!multi->admin) {
curlx_free(multi);
return NULL;
}
multi->admin->multi = multi;
multi->admin->state.internal = TRUE;
/* Now we can use curlx_* things safely */
curlx_pnow(&multi->now);
Curl_timeouts_init(&multi->timeouts, &multi->now);
multi_timeouts_init(multi->admin);
Curl_dnscache_init(&multi->dnscache, dnssize);
Curl_mntfy_init(multi);
Curl_multi_ev_init(multi, ev_hashsize);
@ -269,14 +284,6 @@ struct Curl_multi *Curl_multi_handle(uint32_t xfer_table_size,
Curl_uint32_tbl_resize(&multi->xfers, xfer_table_size))
goto error;
multi->admin = curl_easy_init();
if(!multi->admin)
goto error;
/* Initialize admin handle to operate inside this multi */
multi->admin->multi = multi;
multi->admin->state.internal = TRUE;
multi_timeouts_init(multi->admin);
#ifdef DEBUGBUILD
if(getenv("CURL_DEBUG"))
multi->admin->set.verbose = TRUE;