]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
vtls: make curl_global_sslset thread-safe
authorJay Satiro <raysatiro@yahoo.com>
Wed, 15 Jun 2022 06:20:49 +0000 (02:20 -0400)
committerJay Satiro <raysatiro@yahoo.com>
Thu, 16 Jun 2022 07:18:40 +0000 (03:18 -0400)
.. and update some docs to explain curl_global_* is now thread-safe.

Follow-up to 23af112 which made curl_global_init/cleanup thread-safe.

Closes https://github.com/curl/curl/pull/9016

docs/libcurl/curl_global_cleanup.3
docs/libcurl/curl_global_init.3
docs/libcurl/curl_global_sslset.3
docs/libcurl/libcurl-thread.3
docs/libcurl/libcurl.3
lib/easy.c
lib/vtls/vtls.c
lib/vtls/vtls.h

index 1c2dd9cfeaf742189da06abec2418837771e5786..983f03422f6cc637e3b9e62c6a72d1f9d1e2f884 100644 (file)
@@ -36,7 +36,11 @@ This function releases resources acquired by \fIcurl_global_init(3)\fP.
 You should call \fIcurl_global_cleanup(3)\fP once for each call you make to
 \fIcurl_global_init(3)\fP, after you are done using libcurl.
 
-\fBThis function is not thread safe.\fP You must not call it when any other
+This function is thread-safe since libcurl 7.84.0 if
+\fIcurl_version_info(3)\fP has the CURL_VERSION_THREADSAFE feature bit set
+(most platforms).
+
+If this is not thread-safe, you must not call this function when any other
 thread in the program (i.e. a thread sharing the same memory) is running.
 This does not just mean no other thread that is using libcurl. Because
 \fIcurl_global_cleanup(3)\fP calls functions of other libraries that are
index de0251e2c1e07d5d25fc73fe82ca1e5f6c98ac3b..fd33ccd99dc4ea11e80b13dcb2bcbabe93d81294 100644 (file)
@@ -47,7 +47,7 @@ value unless you are familiar with it and mean to control internal operations
 of libcurl.
 
 This function is thread-safe since libcurl 7.84.0 if
-\fIcurl_version_info(3)\fP has CURL_VERSION_THREADSAFE feature bit set
+\fIcurl_version_info(3)\fP has the CURL_VERSION_THREADSAFE feature bit set
 (most platforms).
 
 If this is not thread-safe, you must not call this function when any other
index c0ebd5a49214368e41b21943e1f31e1156a32e6a..1b99f96dabd80534da4081a7004e967231117495 100644 (file)
@@ -81,7 +81,11 @@ function again to try to select a different backend.
 The SSL backend can be set only once. If it has already been set, a subsequent
 attempt to change it will result in a \fBCURLSSLSET_TOO_LATE\fP.
 
-\fBThis function is not thread safe.\fP You must not call it when any other
+This function is thread-safe since libcurl 7.84.0 if
+\fIcurl_version_info(3)\fP has the CURL_VERSION_THREADSAFE feature bit set
+(most platforms).
+
+If this is not thread-safe, you must not call this function when any other
 thread in the program (i.e. a thread sharing the same memory) is running.
 This does not just mean no other thread that is using libcurl.
 .SH EXAMPLE
index 3e316a853ff545f7e5ebcab40d6e2a566e0e4d63..1b00b90d10768c4d420bb9d0418dad208856fda8 100644 (file)
@@ -94,7 +94,11 @@ problem reports on *BSD (at least in the past, they may be working fine these
 days). Some operating systems that are known to have solid and working thread
 support are Linux, Solaris and Windows.
 .IP "curl_global_* functions"
-These functions are not thread safe. If you are using libcurl with multiple
+These functions are thread-safe since libcurl 7.84.0 if
+\fIcurl_version_info(3)\fP has the CURL_VERSION_THREADSAFE feature bit set
+(most platforms).
+
+If these functions are not thread-safe and you are using libcurl with multiple
 threads it is especially important that before use you call
 \fIcurl_global_init(3)\fP or \fIcurl_global_init_mem(3)\fP to explicitly
 initialize the library and its dependents, rather than rely on the "lazy"
index d5ba1f5c2f010d28bb2a93fd42fd5d74657cd3c8..5f3e264daa7a0395be11e0cf852ba9afc92202fb 100644 (file)
@@ -154,28 +154,31 @@ that library that describes the SSL protocol.
 allocate resources (e.g. the memory for the GNU TLS tree mentioned above), so
 the companion function \fIcurl_global_cleanup(3)\fP releases them.
 
-The basic rule for constructing a program that uses libcurl is this: Call
+The global constant functions are thread-safe since libcurl 7.84.0 if
+\fIcurl_version_info(3)\fP has the CURL_VERSION_THREADSAFE feature bit set
+(most platforms). Read \fIlibcurl-thread(3)\fP for thread safety guidelines.
+
+If the global constant functions are \fInot thread safe\fP, then you must
+not call them when any other thread in the program is running. It
+is not good enough that no other thread is using libcurl at the time,
+because these functions internally call similar functions of other
+libraries, and those functions are similarly thread-unsafe. You cannot
+generally know what these libraries are, or whether other threads are
+using them.
+
+If the global constant functions are \fInot thread safe\fP, then the basic rule
+for constructing a program that uses libcurl is this: Call
 \fIcurl_global_init(3)\fP, with a \fICURL_GLOBAL_ALL\fP argument, immediately
 after the program starts, while it is still only one thread and before it uses
 libcurl at all. Call \fIcurl_global_cleanup(3)\fP immediately before the
 program exits, when the program is again only one thread and after its last
 use of libcurl.
 
-You can call both of these multiple times, as long as all calls meet
-these requirements and the number of calls to each is the same.
-
 It is not actually required that the functions be called at the beginning
 and end of the program -- that is just usually the easiest way to do it.
-It \fIis\fP required that the functions be called when no other thread
-in the program is running.
 
-These global constant functions are \fInot thread safe\fP, so you must
-not call them when any other thread in the program is running. It
-is not good enough that no other thread is using libcurl at the time,
-because these functions internally call similar functions of other
-libraries, and those functions are similarly thread-unsafe. You cannot
-generally know what these libraries are, or whether other threads are
-using them.
+You can call both of these multiple times, as long as all calls meet
+these requirements and the number of calls to each is the same.
 
 The global constant situation merits special consideration when the
 code you are writing to use libcurl is not the main program, but rather
index 71751e35a5951dad74f637d786a3eb55e2c54349..aa642015fed45060bfa118c5f9563332ac315b83 100644 (file)
@@ -315,6 +315,23 @@ void curl_global_cleanup(void)
   global_init_unlock();
 }
 
+/*
+ * curl_global_sslset() globally initializes the SSL backend to use.
+ */
+CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
+                              const curl_ssl_backend ***avail)
+{
+  CURLsslset rc;
+
+  global_init_lock();
+
+  rc = Curl_init_sslset_nolock(id, name, avail);
+
+  global_init_unlock();
+
+  return rc;
+}
+
 /*
  * curl_easy_init() is the external interface to alloc, setup and init an
  * easy handle that is returned. If anything goes wrong, NULL is returned.
index aa3dda3d25b2558f1fb78676289738a6bca7f84d..faa1b51417da8fb32143f1f5aeaaf92c293698db 100644 (file)
@@ -1456,8 +1456,10 @@ static int multissl_setup(const struct Curl_ssl *backend)
   return 0;
 }
 
-CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
-                              const curl_ssl_backend ***avail)
+/* This function is used to select the SSL backend to use. It is called by
+   curl_global_sslset (easy.c) which uses the global init lock. */
+CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name,
+                                   const curl_ssl_backend ***avail)
 {
   int i;
 
@@ -1486,8 +1488,8 @@ CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
 }
 
 #else /* USE_SSL */
-CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
-                              const curl_ssl_backend ***avail)
+CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name,
+                                   const curl_ssl_backend ***avail)
 {
   (void)id;
   (void)name;
index 08c7ac31daee9e85c1e1e8335b653afc71e2e658..e1e58f4215e4c9248d1811d6254f2f60f6908623 100644 (file)
@@ -125,6 +125,9 @@ struct curl_slist *Curl_none_engines_list(struct Curl_easy *data);
 bool Curl_none_false_start(void);
 bool Curl_ssl_tls13_ciphersuites(void);
 
+CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name,
+                                   const curl_ssl_backend ***avail);
+
 #include "openssl.h"        /* OpenSSL versions */
 #include "gtls.h"           /* GnuTLS versions */
 #include "nssg.h"           /* NSS versions */