I've gotten a small test program which shows this issue but you would
need to setup an apache server to test it.

I've tried this with both curl 7.16.1 and 7.20.0.
In this case I had an apache server with a PKCS12 cert.
Every so often this crashes. (it's about 50% for me)
Every time it crashes it happens as the threads are starting... if it
makes it past startup then it runs fine.

Am I perhaps using this incorrectly?



#include <stdio.h>
#include <pthread.h>
#include <curl/curl.h>
 
#include "openssl/crypto.h"

#define NUMT 16
 
static void *pull_one_url(void *url)
{
  CURL *curl;
  int i;
  char buffer[CURL_ERROR_SIZE];
  int num_tries = 100;
  int num_successes = 0;
 
  curl = curl_easy_init();
  curl_easy_setopt(curl, CURLOPT_URL, "https://10.17.11.31";);
  curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
  curl_easy_setopt(curl, CURLOPT_SSLCERT, "mycert.pfx");
  curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "p12");
  curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "exportpass");
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
  curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
  curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
  curl_easy_setopt(curl, CURLOPT_DNS_USE_GLOBAL_CACHE, 0L);
  curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_IGNORED);
  curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, buffer);

  for( i = 0; i < num_tries; i++ )
  {
      if( curl_easy_perform(curl) == 0 )
          num_successes++;
      else
      {
          fprintf(stderr, "ERROR: %s\n", buffer);
      }
  }
  curl_easy_cleanup(curl);

  printf("DEBUG: %ud :: %i/%i\n", (unsigned long)pthread_self(), num_successes, num_tries);
 
  return NULL;
}
 
static pthread_mutex_t **locks = NULL;
static int n_locks = 0;

static void
ssl_lock(int mode, int n, const char *file, int line)
{
    if (mode & CRYPTO_LOCK) pthread_mutex_lock(locks[n]);
    else pthread_mutex_unlock(locks[n]);
}
 
static unsigned long
ssl_thread_id(void)
{
    return (unsigned long)pthread_self();
}

int main(int argc, char **argv)
{
    pthread_t tid[NUMT];
    int i;
    int error;
  
  n_locks = CRYPTO_num_locks();
  if (n_locks) {
      locks = (pthread_mutex_t **) malloc(n_locks * sizeof(*locks));
      for (i=0; i < n_locks; i++) {
          locks[i] = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
          if( pthread_mutex_init(locks[i], NULL) )
              exit(1);
      }
        
      CRYPTO_set_locking_callback(ssl_lock);
      CRYPTO_set_id_callback(ssl_thread_id);
  }

  /* Must initialize libcurl before any threads are started */ 
  curl_global_init(CURL_GLOBAL_ALL);

  {
      int cnt = 0;
      for( cnt = 0; cnt < 1; cnt++ )
      {
          for(i=0; i< NUMT; i++) {
              error = pthread_create(&tid[i],
                                     NULL, /* default attributes please */ 
                                     pull_one_url,
                                     (void *)NULL);
              if(0 != error)
                  fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
              else
                  fprintf(stderr, "Thread %d, started\n", i);
          }
 
          /* now wait for all threads to terminate */ 
          for(i=0; i< NUMT; i++) {
              error = pthread_join(tid[i], NULL);
              fprintf(stderr, "Thread %d terminated\n", i);
          }
      }
  }
 
  return 0;
}

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html

Reply via email to