curl-library
Is Curl_resolve thread safe?
Date: Wed, 18 Aug 2004 22:32:35 +0100
Is Curl_resolve thread safe()?
Valgrind reports errors such as this on every call.
The unititialised value is of course more serious than the mutex is not
locked error.
This is on Fedora Core 1 Linux/x86.
--snip--
==29426== Thread 3:
==29426== pthread_mutex_unlock: mutex is not locked
==29426== at 0x37CF8B: __pthread_mutex_unlock (vg_libpthread.c:993)
==29426== by 0x4B415B: _IO_fclose@@GLIBC_2.1 (in /lib/libc-2.3.2.so)
==29426== by 0x544DD8: do_init (in /lib/libc-2.3.2.so)
==29426== by 0x37E07C: __pthread_once (vg_libpthread.c:1551)
==29426== by 0x544719: _res_hconf_init (in /lib/libc-2.3.2.so)
==29426== by 0x548B12: gethostbyaddr_r@@GLIBC_2.1.2 (in
/lib/libc-2.3.2.so)
==29426== by 0x51B77A: gaih_inet (in /lib/libc-2.3.2.so)
==29426== by 0x51C923: __GI_getaddrinfo (in /lib/libc-2.3.2.so)
==29426== by 0xF16CA6: (within /usr/lib/libcurl.so.2.0.2)
==29426== by 0xF16A4F: Curl_resolv (in /usr/lib/libcurl.so.2.0.2)
==29426== by 0xF22801: (within /usr/lib/libcurl.so.2.0.2)
==29426== by 0xF23A9B: Curl_connect (in /usr/lib/libcurl.so.2.0.2)
==29426== by 0xF2E52C: Curl_perform (in /usr/lib/libcurl.so.2.0.2)
==29426== by 0xF2E9E0: curl_easy_perform (in /usr/lib/libcurl.so.2.0.2)
==29426== by 0xB88B81: getURL (mbox.c:2550)
==29426== by 0x37C6E9: thread_wrapper (vg_libpthread.c:667)
==29426== by 0x143ABF: ??? (vg_scheduler.c:2142)
==29426==
==29426== Thread 3:
==29426== Use of uninitialised value of size 4
==29426== at 0x5489D6: gethostbyaddr_r@@GLIBC_2.1.2 (in
/lib/libc-2.3.2.so)
==29426== by 0x51B77A: gaih_inet (in /lib/libc-2.3.2.so)
==29426== by 0x51C923: __GI_getaddrinfo (in /lib/libc-2.3.2.so)
==29426== by 0xF16CA6: (within /usr/lib/libcurl.so.2.0.2)
==29426== by 0xF16A4F: Curl_resolv (in /usr/lib/libcurl.so.2.0.2)
==29426== by 0xF22801: (within /usr/lib/libcurl.so.2.0.2)
==29426== by 0xF23A9B: Curl_connect (in /usr/lib/libcurl.so.2.0.2)
==29426== by 0xF2E52C: Curl_perform (in /usr/lib/libcurl.so.2.0.2)
==29426== by 0xF2E9E0: curl_easy_perform (in /usr/lib/libcurl.so.2.0.2)
==29426== by 0xB88B81: getURL (mbox.c:2550)
==29426== by 0x37C6E9: thread_wrapper (vg_libpthread.c:667)
==29426== by 0x143ABF: ??? (vg_scheduler.c:2142)
--snip--
With this code:
static void *
getURL(void *a)
{
char *fout;
CURL *curl;
FILE *fp;
struct curl_slist *headers;
static int initialised = 0;
static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
struct arg *arg = (struct arg *)a;
const char *url = arg->url;
const char *dir = arg->dir;
const char *filename = arg->filename;
pthread_mutex_lock(&init_mutex);
if(!initialised) {
if(curl_global_init(CURL_GLOBAL_NOTHING) != 0) {
pthread_mutex_unlock(&init_mutex);
return NULL;
}
initialised = 1;
}
pthread_mutex_unlock(&init_mutex);
curl = curl_easy_init();
if(curl == NULL)
return NULL;
(void)curl_easy_setopt(curl, CURLOPT_USERAGENT,
"www.bandsman.co.uk");
if(curl_easy_setopt(curl, CURLOPT_URL, url) != 0)
return NULL;
fout = cli_malloc(strlen(dir) + strlen(filename) + 2);
if(fout == NULL) {
curl_easy_cleanup(curl);
return NULL;
}
sprintf(fout, "%s/%s", dir, filename);
fp = fopen(fout, "w");
if(fp == NULL) {
perror(fout);
free(fout);
curl_easy_cleanup(curl);
return NULL;
}
if(curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp) != 0) {
fclose(fp);
free(fout);
curl_easy_cleanup(curl);
return NULL;
}
headers = curl_slist_append(NULL, "Pragma:");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
/* These should be customisable */
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
#ifdef CURLOPT_MAXFILESIZE
curl_easy_setopt(curl, CURLOPT_MAXFILESIZE, 50*1024);
#endif
curl_easy_setopt(curl, CURLOPT_DNS_USE_GLOBAL_CACHE, 0);
if(curl_easy_perform(curl) != CURLE_OK) {
cli_warnmsg("URL %s failed to download\n", url);
unlink(fout);
}
fclose(fp);
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
free(fout);
return NULL;
}
-Nigel
Received on 2004-08-18