blob: c3efe2692c9cb692a8b75960d57715be2329ced8 [file] [log] [blame]
// 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_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 {
return thread_id_ == PlatformThread::CurrentId();
}
// 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
bool delete_later = false;
{
AutoLock lock(message_loop_lock_);
if (target_message_loop_) {
base::ThreadRestrictions::ScopedAllowSingleton allow_singleton;
if (MessageLoop::current() != target_message_loop_) {
target_message_loop_->DeleteSoon(FROM_HERE, this);
delete_later = true;
}
}
}
if (!delete_later)
delete this;
}
MessageLoopProxyImpl::MessageLoopProxyImpl()
: thread_id_(PlatformThread::CurrentId()),
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