diff options
Diffstat (limited to 'base/message_loop/message_loop_proxy_impl.cc')
-rw-r--r-- | base/message_loop/message_loop_proxy_impl.cc | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/base/message_loop/message_loop_proxy_impl.cc b/base/message_loop/message_loop_proxy_impl.cc new file mode 100644 index 0000000..7dc8caa --- /dev/null +++ b/base/message_loop/message_loop_proxy_impl.cc @@ -0,0 +1,92 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/message_loop/message_loop_proxy_impl.h" + +#include "base/location.h" +#include "base/threading/thread_restrictions.h" + +namespace base { + +MessageLoopProxyImpl::~MessageLoopProxyImpl() { +} + +bool MessageLoopProxyImpl::PostDelayedTask( + const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeDelta delay) { + return PostTaskHelper(from_here, task, delay, true); +} + +bool MessageLoopProxyImpl::PostNonNestableDelayedTask( + const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeDelta delay) { + return PostTaskHelper(from_here, task, delay, false); +} + +bool MessageLoopProxyImpl::RunsTasksOnCurrentThread() 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; + AutoLock lock(message_loop_lock_); + return (target_message_loop_ && + (MessageLoop::current() == target_message_loop_)); +} + +// MessageLoop::DestructionObserver implementation +void MessageLoopProxyImpl::WillDestroyCurrentMessageLoop() { + AutoLock lock(message_loop_lock_); + target_message_loop_ = NULL; +} + +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_); + if (target_message_loop_ && + (MessageLoop::current() != target_message_loop_)) { + target_message_loop_->DeleteSoon(FROM_HERE, this); + delete_later = true; + } + } + if (!delete_later) + delete this; +} + +MessageLoopProxyImpl::MessageLoopProxyImpl() + : target_message_loop_(MessageLoop::current()) { +} + +bool MessageLoopProxyImpl::PostTaskHelper( + const tracked_objects::Location& from_here, const base::Closure& task, + base::TimeDelta delay, bool nestable) { + AutoLock lock(message_loop_lock_); + if (target_message_loop_) { + if (nestable) { + target_message_loop_->PostDelayedTask(from_here, task, delay); + } else { + target_message_loop_->PostNonNestableDelayedTask(from_here, task, delay); + } + return true; + } + return false; +} + +scoped_refptr<MessageLoopProxy> +MessageLoopProxy::current() { + MessageLoop* cur_loop = MessageLoop::current(); + if (!cur_loop) + return NULL; + return cur_loop->message_loop_proxy(); +} + +} // namespace base |