* </DESC>
*/
/* A multi-threaded example that uses pthreads and fetches 4 remote files at
- * once over HTTPS. The lock callbacks and stuff assume OpenSSL <1.1 or GnuTLS
- * (libgcrypt) so far.
+ * once over HTTPS.
*
- * OpenSSL docs for this:
- * https://www.openssl.org/docs/man1.0.2/man3/CRYPTO_num_locks.html
- * gcrypt docs for this:
- * https://gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html
+ * Recent versions of OpenSSL and GnuTLS are thread safe by design, assuming
+ * support for the underlying OS threading API is built-in. Older revisions
+ * of this example demonstrated locking callbacks for the SSL library, which
+ * are no longer necessary. An older revision with callbacks can be found at
+ * https://github.com/curl/curl/blob/curl-7_88_1/docs/examples/threaded-ssl.c
*/
#define USE_OPENSSL /* or USE_GNUTLS accordingly */
#define NUMT 4
-/* we have this global to let the callback get easy access to it */
-static pthread_mutex_t *lockarray;
-
-#ifdef USE_OPENSSL
-#include <openssl/crypto.h>
-static void lock_callback(int mode, int type, char *file, int line)
-{
- (void)file;
- (void)line;
- if(mode & CRYPTO_LOCK) {
- pthread_mutex_lock(&(lockarray[type]));
- }
- else {
- pthread_mutex_unlock(&(lockarray[type]));
- }
-}
-
-static unsigned long thread_id(void)
-{
- unsigned long ret;
-
- ret = (unsigned long)pthread_self();
- return ret;
-}
-
-static void init_locks(void)
-{
- int i;
-
- lockarray = (pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() *
- sizeof(pthread_mutex_t));
- for(i = 0; i<CRYPTO_num_locks(); i++) {
- pthread_mutex_init(&(lockarray[i]), NULL);
- }
-
- CRYPTO_set_id_callback((unsigned long (*)())thread_id);
- CRYPTO_set_locking_callback((void (*)())lock_callback);
-}
-
-static void kill_locks(void)
-{
- int i;
-
- CRYPTO_set_locking_callback(NULL);
- for(i = 0; i<CRYPTO_num_locks(); i++)
- pthread_mutex_destroy(&(lockarray[i]));
-
- OPENSSL_free(lockarray);
-}
-#endif
-
-#ifdef USE_GNUTLS
-#include <gcrypt.h>
-#include <errno.h>
-
-GCRY_THREAD_OPTION_PTHREAD_IMPL;
-
-void init_locks(void)
-{
- gcry_control(GCRYCTL_SET_THREAD_CBS);
-}
-
-#define kill_locks()
-#endif
-
/* List of URLs to fetch.*/
const char * const urls[]= {
"https://www.example.com/",
/* Must initialize libcurl before any threads are started */
curl_global_init(CURL_GLOBAL_ALL);
- init_locks();
-
for(i = 0; i< NUMT; i++) {
int error = pthread_create(&tid[i],
NULL, /* default attributes please */
fprintf(stderr, "Thread %d terminated\n", i);
}
- kill_locks();
-
return 0;
}