Browse Source

asyn-ares: fix data race warning

- Store the c-ares version during global init.

Prior to this change several threads could write the same data to a
static int variable at the same time. Though in practice it's not a
problem ThreadSanitizer may warn.

Reported-by: Nikita Taranov
Assisted-by: Jay Satiro

Fixes #13065
Closes #13000
Robert Moreton 2 months ago
parent
commit
835e4cb1d5
1 changed files with 8 additions and 8 deletions
  1. 8 8
      lib/asyn-ares.c

+ 8 - 8
lib/asyn-ares.c

@@ -122,6 +122,8 @@ struct thread_data {
 
 #define CARES_TIMEOUT_PER_ATTEMPT 2000
 
+static int ares_ver = 0;
+
 /*
  * Curl_resolver_global_init() - the generic low-level asynchronous name
  * resolve API.  Called from curl_global_init() to initialize global resolver
@@ -134,6 +136,7 @@ int Curl_resolver_global_init(void)
     return CURLE_FAILED_INIT;
   }
 #endif
+  ares_version(&ares_ver);
   return CURLE_OK;
 }
 
@@ -173,16 +176,8 @@ CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver)
   int status;
   struct ares_options options;
   int optmask = ARES_OPT_SOCK_STATE_CB;
-  static int ares_ver = 0;
   options.sock_state_cb = sock_state_cb;
   options.sock_state_cb_data = easy;
-  if(ares_ver == 0)
-    ares_version(&ares_ver);
-
-  if(ares_ver < 0x011400) { /* c-ares included similar change since 1.20.0 */
-    options.timeout = CARES_TIMEOUT_PER_ATTEMPT;
-    optmask |= ARES_OPT_TIMEOUTMS;
-  }
 
   /*
      if c ares < 1.20.0: curl set timeout to CARES_TIMEOUT_PER_ATTEMPT (2s)
@@ -193,6 +188,11 @@ CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver)
      if c-ares >= 1.24.0, user can set the timeout via /etc/resolv.conf to
      overwrite c-ares' timeout.
   */
+  DEBUGASSERT(ares_ver);
+  if(ares_ver < 0x011400) {
+    options.timeout = CARES_TIMEOUT_PER_ATTEMPT;
+    optmask |= ARES_OPT_TIMEOUTMS;
+  }
 
   status = ares_init_options((ares_channel*)resolver, &options, optmask);
   if(status != ARES_SUCCESS) {