Chromium Code Reviews| Index: net/base/cert_verifier.cc |
| diff --git a/net/base/cert_verifier.cc b/net/base/cert_verifier.cc |
| index 4e941335653adea573ae13ae3dadcb18ebed3c01..6bb51243f8d26e9bf5246d0d2dcc2c826ee81fa4 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,8 @@ class CertVerifier::Request : |
| callback_(callback), |
| origin_loop_(MessageLoop::current()), |
| error_(OK) { |
| + if (origin_loop_) |
|
wtc
2010/11/15 23:57:15
Let's remove this null pointer check for origin_lo
Zachary Kuznia
2010/11/16 01:14:39
Done.
|
| + origin_loop_->AddDestructionObserver(this); |
| } |
| void DoVerify() { |
| @@ -84,15 +88,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() { |
| + { |
| + 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_; |
| @@ -114,6 +145,12 @@ class CertVerifier::Request : |
| CertVerifyResult result_; |
| }; |
| +struct CertVerifier::RequestTraits { |
| + static void Destruct(const CertVerifier::Request* request) { |
| + const_cast<CertVerifier::Request*>(request)->OnDestruct(); |
| + } |
| +}; |
| + |
| //----------------------------------------------------------------------------- |
| CertVerifier::CertVerifier() { |