summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/message_loop_proxy.h3
-rw-r--r--base/message_loop_proxy_impl.cc5
-rw-r--r--net/base/cert_verifier.cc35
3 files changed, 26 insertions, 17 deletions
diff --git a/base/message_loop_proxy.h b/base/message_loop_proxy.h
index 4d38155..6a8cbe8 100644
--- a/base/message_loop_proxy.h
+++ b/base/message_loop_proxy.h
@@ -16,7 +16,8 @@ struct MessageLoopProxyTraits;
// This class provides a thread-safe refcounted interface to the Post* methods
// of a message loop. This class can outlive the target message loop. You can
-// obtain a MessageLoopProxy via Thread::message_loop_proxy().
+// obtain a MessageLoopProxy via Thread::message_loop_proxy() or
+// MessageLoopProxy::CreateForCurrentThread().
class MessageLoopProxy
: public base::RefCountedThreadSafe<MessageLoopProxy,
MessageLoopProxyTraits> {
diff --git a/base/message_loop_proxy_impl.cc b/base/message_loop_proxy_impl.cc
index 7998a94..c0619aa 100644
--- a/base/message_loop_proxy_impl.cc
+++ b/base/message_loop_proxy_impl.cc
@@ -78,6 +78,11 @@ bool MessageLoopProxyImpl::PostTaskHelper(
}
void MessageLoopProxyImpl::OnDestruct() const {
+ // We shouldn't use MessageLoop::current() since it uses LazyInstance which
+ // may be deleted by ~AtExitManager when a WorkerPool thread calls this
+ // function.
+ // http://crbug.com/63678
+ base::ThreadRestrictions::ScopedAllowSingleton allow_singleton;
bool delete_later = false;
{
AutoLock lock(message_loop_lock_);
diff --git a/net/base/cert_verifier.cc b/net/base/cert_verifier.cc
index 4e94133..ae910b4 100644
--- a/net/base/cert_verifier.cc
+++ b/net/base/cert_verifier.cc
@@ -8,7 +8,9 @@
#include <private/pprthred.h> // PR_DetatchThread
#endif
-#include "base/message_loop.h"
+#include "base/lock.h"
+#include "base/message_loop_proxy.h"
+#include "base/scoped_ptr.h"
#include "base/worker_pool.h"
#include "net/base/cert_verify_result.h"
#include "net/base/net_errors.h"
@@ -31,7 +33,7 @@ class CertVerifier::Request :
verifier_(verifier),
verify_result_(verify_result),
callback_(callback),
- origin_loop_(MessageLoop::current()),
+ origin_loop_proxy_(base::MessageLoopProxy::CreateForCurrentThread()),
error_(OK) {
}
@@ -49,20 +51,16 @@ class CertVerifier::Request :
PR_DetachThread();
#endif
- Task* reply = NewRunnableMethod(this, &Request::DoCallback);
+ scoped_ptr<Task> reply(NewRunnableMethod(this, &Request::DoCallback));
// The origin loop could go away while we are trying to post to it, so we
// need to call its PostTask method inside a lock. See ~CertVerifier.
- {
- AutoLock locked(origin_loop_lock_);
- if (origin_loop_) {
- origin_loop_->PostTask(FROM_HERE, reply);
- reply = NULL;
- }
+ AutoLock locked(origin_loop_proxy_lock_);
+ if (origin_loop_proxy_) {
+ bool posted = origin_loop_proxy_->PostTask(FROM_HERE, reply.release());
+ // TODO(willchan): Fix leaks and then change this to a DCHECK.
+ LOG_IF(ERROR, !posted) << "Leaked CertVerifier!";
}
-
- // Does nothing if it got posted.
- delete reply;
}
void DoCallback() {
@@ -85,8 +83,8 @@ class CertVerifier::Request :
void Cancel() {
verifier_ = NULL;
- AutoLock locked(origin_loop_lock_);
- origin_loop_ = NULL;
+ AutoLock locked(origin_loop_proxy_lock_);
+ origin_loop_proxy_ = NULL;
}
private:
@@ -106,8 +104,13 @@ class CertVerifier::Request :
CompletionCallback* callback_;
// Used to post ourselves onto the origin thread.
- Lock origin_loop_lock_;
- MessageLoop* origin_loop_;
+ Lock origin_loop_proxy_lock_;
+ // Use a MessageLoopProxy in case the owner of the CertVerifier is leaked, so
+ // this code won't crash: http://crbug.com/42275. If this is leaked, then it
+ // doesn't get Cancel()'d, so |origin_loop_proxy_| doesn't get NULL'd out. If
+ // the MessageLoop goes away, then if we had used a MessageLoop, this would
+ // crash.
+ scoped_refptr<base::MessageLoopProxy> origin_loop_proxy_;
// Assigned on the worker thread, read on the origin thread.
int error_;