Index: net/base/x509_certificate.cc |
=================================================================== |
--- net/base/x509_certificate.cc (revision 66806) |
+++ net/base/x509_certificate.cc (working copy) |
@@ -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 @@ |
// 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 @@ |
// 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 @@ |
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 @@ |
// 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 @@ |
// 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 @@ |
// 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 @@ |
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 @@ |
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() { |
// 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) |