diff -u --recursive curl-7.18.2/lib/nss.c curl-7.18.2.new/lib/nss.c --- curl-7.18.2/lib/nss.c 2008-09-16 11:13:00.000000000 -0400 +++ curl-7.18.2.new/lib/nss.c 2008-09-16 11:29:13.000000000 -0400 @@ -73,6 +73,8 @@ PRFileDesc *PR_ImportTCPSocket(PRInt32 osfd); +PRLock * nss_initlock = NULL; + int initialized = 0; #define HANDSHAKE_TIMEOUT 30 @@ -719,8 +721,11 @@ */ int Curl_nss_init(void) { - if(!initialized) + /* curl_global_init() is not thread-safe so this test is ok */ + if (nss_initlock == NULL) { PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256); + nss_initlock = PR_NewLock(); + } /* We will actually initialize NSS later */ @@ -730,7 +735,17 @@ /* Global cleanup */ void Curl_nss_cleanup(void) { - NSS_Shutdown(); + /* This function isn't required to be threadsafe and this is only done + * as a safety feature. + */ + PR_Lock(nss_initlock); + if (initialized) + NSS_Shutdown(); + PR_Unlock(nss_initlock); + + PR_DestroyLock(nss_initlock); + nss_initlock = NULL; + initialized = 0; } @@ -808,7 +823,8 @@ return CURLE_OK; /* FIXME. NSS doesn't support multiple databases open at the same time. */ - if(!initialized) { + PR_Lock(nss_initlock); + if(!initialized && !NSS_IsInitialized()) { initialized = 1; certDir = getenv("SSL_DIR"); /* Look in $SSL_DIR */ @@ -832,6 +848,8 @@ if(rv != SECSuccess) { infof(conn->data, "Unable to initialize NSS database\n"); curlerr = CURLE_SSL_CACERT_BADFILE; + PR_Unlock(nss_initlock); + initialized = 0; goto error; } @@ -854,6 +872,7 @@ } #endif } + PR_Unlock(nss_initlock); model = PR_NewTCPSocket(); if(!model) Only in curl-7.18.2.new/lib: nss.c.orig