| Index: net/base/x509_certificate.cc
|
| diff --git a/net/base/x509_certificate.cc b/net/base/x509_certificate.cc
|
| index d93d270501113687631bd1eaec2fd9789ca1cee8..310defbb782fbf15ee907ccfa35fdae056025fa9 100644
|
| --- a/net/base/x509_certificate.cc
|
| +++ b/net/base/x509_certificate.cc
|
| @@ -6,9 +6,9 @@
|
|
|
| #include <map>
|
|
|
| +#include "base/lazy_instance.h"
|
| #include "base/logging.h"
|
| #include "base/metrics/histogram.h"
|
| -#include "base/singleton.h"
|
| #include "base/string_piece.h"
|
| #include "base/time.h"
|
| #include "net/base/pem_tokenizer.h"
|
| @@ -39,17 +39,6 @@ const char kCertificateHeader[] = "CERTIFICATE";
|
| // The PEM block header used for PKCS#7 data
|
| const char kPKCS7Header[] = "PKCS7";
|
|
|
| -} // namespace
|
| -
|
| -bool X509Certificate::LessThan::operator()(X509Certificate* lhs,
|
| - X509Certificate* rhs) const {
|
| - if (lhs == rhs)
|
| - return false;
|
| -
|
| - SHA1FingerprintLessThan fingerprint_functor;
|
| - return fingerprint_functor(lhs->fingerprint_, rhs->fingerprint_);
|
| -}
|
| -
|
| // A thread-safe cache for X509Certificate objects.
|
| //
|
| // The cache does not hold a reference to the certificate objects. The objects
|
| @@ -57,9 +46,8 @@ bool X509Certificate::LessThan::operator()(X509Certificate* lhs,
|
| // will be holding dead pointers to the objects).
|
| // TODO(rsleevi): There exists a chance of a use-after-free, due to a race
|
| // between Find() and Remove(). See http://crbug.com/49377
|
| -class X509Certificate::Cache {
|
| +class X509CertificateCache {
|
| public:
|
| - static Cache* GetInstance();
|
| void Insert(X509Certificate* cert);
|
| void Remove(X509Certificate* cert);
|
| X509Certificate* Find(const SHA1Fingerprint& fingerprint);
|
| @@ -68,9 +56,10 @@ class X509Certificate::Cache {
|
| typedef std::map<SHA1Fingerprint, X509Certificate*, SHA1FingerprintLessThan>
|
| CertMap;
|
|
|
| - // Obtain an instance of X509Certificate::Cache via GetInstance().
|
| - Cache() {}
|
| - friend struct DefaultSingletonTraits<Cache>;
|
| + // Obtain an instance of X509CertificateCache via a LazyInstance.
|
| + X509CertificateCache() {}
|
| + ~X509CertificateCache() {}
|
| + friend struct base::DefaultLazyInstanceTraits<X509CertificateCache>;
|
|
|
| // You must acquire this lock before using any private data of this object.
|
| // You must not block while holding this lock.
|
| @@ -79,18 +68,16 @@ class X509Certificate::Cache {
|
| // The certificate cache. You must acquire |lock_| before using |cache_|.
|
| CertMap cache_;
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(Cache);
|
| + DISALLOW_COPY_AND_ASSIGN(X509CertificateCache);
|
| };
|
|
|
| -// Get the singleton object for the cache.
|
| -// static
|
| -X509Certificate::Cache* X509Certificate::Cache::GetInstance() {
|
| - return Singleton<X509Certificate::Cache>::get();
|
| -}
|
| +base::LazyInstance<X509CertificateCache,
|
| + base::LeakyLazyInstanceTraits<X509CertificateCache> >
|
| + g_x509_certificate_cache(base::LINKER_INITIALIZED);
|
|
|
| // Insert |cert| into the cache. The cache does NOT AddRef |cert|.
|
| // Any existing certificate with the same fingerprint will be replaced.
|
| -void X509Certificate::Cache::Insert(X509Certificate* cert) {
|
| +void X509CertificateCache::Insert(X509Certificate* cert) {
|
| AutoLock lock(lock_);
|
|
|
| DCHECK(!IsNullFingerprint(cert->fingerprint())) <<
|
| @@ -100,7 +87,7 @@ void X509Certificate::Cache::Insert(X509Certificate* cert) {
|
|
|
| // Remove |cert| from the cache. The cache does not assume that |cert| is
|
| // already in the cache.
|
| -void X509Certificate::Cache::Remove(X509Certificate* cert) {
|
| +void X509CertificateCache::Remove(X509Certificate* cert) {
|
| AutoLock lock(lock_);
|
|
|
| CertMap::iterator pos(cache_.find(cert->fingerprint()));
|
| @@ -111,7 +98,7 @@ void X509Certificate::Cache::Remove(X509Certificate* cert) {
|
|
|
| // Find a certificate in the cache with the given fingerprint. If one does
|
| // not exist, this method returns NULL.
|
| -X509Certificate* X509Certificate::Cache::Find(
|
| +X509Certificate* X509CertificateCache::Find(
|
| const SHA1Fingerprint& fingerprint) {
|
| AutoLock lock(lock_);
|
|
|
| @@ -122,6 +109,17 @@ X509Certificate* X509Certificate::Cache::Find(
|
| return pos->second;
|
| };
|
|
|
| +} // namespace
|
| +
|
| +bool X509Certificate::LessThan::operator()(X509Certificate* lhs,
|
| + X509Certificate* rhs) const {
|
| + if (lhs == rhs)
|
| + return false;
|
| +
|
| + SHA1FingerprintLessThan fingerprint_functor;
|
| + return fingerprint_functor(lhs->fingerprint_, rhs->fingerprint_);
|
| +}
|
| +
|
| // static
|
| X509Certificate* X509Certificate::CreateFromHandle(
|
| OSCertHandle cert_handle,
|
| @@ -131,7 +129,7 @@ X509Certificate* X509Certificate::CreateFromHandle(
|
| DCHECK(source != SOURCE_UNUSED);
|
|
|
| // Check if we already have this certificate in memory.
|
| - X509Certificate::Cache* cache = X509Certificate::Cache::GetInstance();
|
| + X509CertificateCache* cache = g_x509_certificate_cache.Pointer();
|
| X509Certificate* cached_cert =
|
| cache->Find(CalculateFingerprint(cert_handle));
|
| if (cached_cert) {
|
| @@ -311,7 +309,7 @@ X509Certificate::X509Certificate(const std::string& subject,
|
|
|
| X509Certificate::~X509Certificate() {
|
| // We might not be in the cache, but it is safe to remove ourselves anyway.
|
| - X509Certificate::Cache::GetInstance()->Remove(this);
|
| + g_x509_certificate_cache.Get().Remove(this);
|
| if (cert_handle_)
|
| FreeOSCertHandle(cert_handle_);
|
| for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i)
|
|
|