Index: net/base/cert_verifier.cc |
diff --git a/net/base/cert_verifier.cc b/net/base/cert_verifier.cc |
index 4e941335653adea573ae13ae3dadcb18ebed3c01..ed3d27a2183660457fb4310661973d8b80a5c67a 100644 |
--- a/net/base/cert_verifier.cc |
+++ b/net/base/cert_verifier.cc |
@@ -17,7 +17,9 @@ |
namespace net { |
class CertVerifier::Request : |
- public base::RefCountedThreadSafe<CertVerifier::Request> { |
+ public base::RefCountedThreadSafe<CertVerifier::Request, |
+ CertVerifier::RequestTraits>, |
+ public MessageLoop::DestructionObserver { |
public: |
Request(CertVerifier* verifier, |
X509Certificate* cert, |
@@ -33,6 +35,7 @@ class CertVerifier::Request : |
callback_(callback), |
origin_loop_(MessageLoop::current()), |
error_(OK) { |
+ origin_loop_->AddDestructionObserver(this); |
} |
void DoVerify() { |
@@ -84,15 +87,42 @@ class CertVerifier::Request : |
void Cancel() { |
verifier_ = NULL; |
+ AutoLock locked(origin_loop_lock_); |
+ if (origin_loop_) { |
+ origin_loop_->RemoveDestructionObserver(this); |
+ origin_loop_ = NULL; |
+ } |
+ } |
+ // MessageLoop::DestructionObserver override. |
+ virtual void WillDestroyCurrentMessageLoop() { |
+ LOG(ERROR) << "CertVerifier wasn't deleted before the thread was deleted."; |
AutoLock locked(origin_loop_lock_); |
origin_loop_ = NULL; |
} |
private: |
friend class base::RefCountedThreadSafe<CertVerifier::Request>; |
+ friend class DeleteTask<CertVerifier::Request>; |
+ friend struct CertVerifier::RequestTraits; |
- ~Request() {} |
+ ~Request() { |
+ Cancel(); |
+ } |
+ |
+ // If we have an origin_loop_, the observer needs to be removed on that |
+ // thread. OnDestruct is called by RequestTraits to ensure this |
+ // happens. |
+ void OnDestruct() const { |
+ { |
+ AutoLock locked(origin_loop_lock_); |
+ if (origin_loop_ && origin_loop_ != MessageLoop::current()) { |
+ origin_loop_->DeleteSoon(FROM_HERE, this); |
+ return; |
+ } |
+ } |
+ delete this; |
+ } |
// Set on the origin thread, read on the worker thread. |
scoped_refptr<X509Certificate> cert_; |
@@ -106,7 +136,7 @@ class CertVerifier::Request : |
CompletionCallback* callback_; |
// Used to post ourselves onto the origin thread. |
- Lock origin_loop_lock_; |
+ mutable Lock origin_loop_lock_; |
MessageLoop* origin_loop_; |
// Assigned on the worker thread, read on the origin thread. |
@@ -114,6 +144,12 @@ class CertVerifier::Request : |
CertVerifyResult result_; |
}; |
+struct CertVerifier::RequestTraits { |
+ static void Destruct(const CertVerifier::Request* request) { |
+ request->OnDestruct(); |
+ } |
+}; |
+ |
//----------------------------------------------------------------------------- |
CertVerifier::CertVerifier() { |