rv = IssuerCache_Create(&issuercache, issuer, dp);
rv = IssuerCache_Create(&issuercache, issuer, subject, dp);
SECStatus AcquireDPCache(CERTCertificate* issuer, SECItem* subject, SECItem* dp,                         int64 t, void* wincx, CRLDPCache** dpcache,                         PRBool* writeLocked){    SECStatus rv = SECSuccess;    CRLIssuerCache* issuercache = NULL;    PORT_Assert(crlcache.lock);    if (!crlcache.lock) {        /* CRL cache is not initialized */        return SECFailure;    }    PR_Lock(crlcache.lock);    rv = GetIssuerCache(&crlcache, subject, &issuercache);    if (SECSuccess != rv) {        PR_Unlock(crlcache.lock);        return SECFailure;    }    if (!issuercache) {        /* there is no cache for this issuer yet. This means this is the           first time we look up a cert from that issuer, and we need to           create the cache. Do it within the global cache lock to ensure           no two threads will simultaneously try to create the same issuer           cache. XXX this could be optimized with a r/w lock at this level           too. But the code would have to check if it already exists when           adding to the hash table */                rv = IssuerCache_Create(&issuercache, issuer, dp);        if (SECSuccess == rv && !issuercache) {            PORT_Assert(issuercache);            rv = SECFailure;        }        if (SECSuccess == rv) {            /* This is the first time we look up a cert of this issuer.               Create the DPCache for this DP . */            rv = IssuerCache_AddDP(issuercache, issuer, subject, dp, dpcache);        }        if (SECSuccess == rv) {            /* lock the DPCache for write to ensure the update happens in this thread */            *writeLocked = PR_TRUE;#ifdef USE_RWLOCK            NSSRWLock_LockWrite((*dpcache)->lock);#else            PR_Lock((*dpcache)->lock);#endif        }                if (SECSuccess == rv) {            /* now add the new issuer cache to the global hash table of issuers */            rv = CRLCache_AddIssuer(subject, issuercache);            if (SECSuccess != rv) {                /* failure */                rv = SECFailure;            }        }        /* now unlock the global cache. We only want to lock the hash table           addition. Holding it longer would hurt scalability */        PR_Unlock(crlcache.lock);        if (SECSuccess != rv && issuercache) {            if (PR_TRUE == *writeLocked) {#ifdef USE_RWLOCK                NSSRWLock_UnlockWrite((*dpcache)->lock);#else                PR_Unlock((*dpcache)->lock);#endif            }            IssuerCache_Destroy(issuercache);            issuercache = NULL;        }        if (SECSuccess != rv) {            return SECFailure;        }    } else {        PR_Unlock(crlcache.lock);        *dpcache = GetDPCache(issuercache, dp);    }    /* we now have a DPCache that we can use for lookups */    /* lock it for read, unless we already locked for write */    if (PR_FALSE == *writeLocked)    {#ifdef USE_RWLOCK        NSSRWLock_LockRead((*dpcache)->lock);#else        PR_Lock((*dpcache)->lock);#endif    }        if (SECSuccess == rv) {        /* currently there is always one and only one DPCache */        PORT_Assert(*dpcache);        if (*dpcache)        {            /* make sure the DP cache is up to date before using it */            rv = DPCache_Update(*dpcache, issuer, t, wincx, PR_FALSE == *writeLocked);        }        else        {            rv = SECFailure;        }    }    return rv;}