1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/message_loop_proxy_impl.h" 6#include "base/threading/thread_restrictions.h" 7 8namespace base { 9 10MessageLoopProxyImpl::~MessageLoopProxyImpl() { 11 AutoLock lock(message_loop_lock_); 12 // If the target message loop still exists, the d'tor WILL execute on the 13 // target loop. 14 if (target_message_loop_) { 15 DCHECK(MessageLoop::current() == target_message_loop_); 16 MessageLoop::current()->RemoveDestructionObserver(this); 17 } 18} 19 20 // MessageLoopProxy implementation 21bool MessageLoopProxyImpl::PostTask(const tracked_objects::Location& from_here, 22 Task* task) { 23 return PostTaskHelper(from_here, task, 0, true); 24} 25 26bool MessageLoopProxyImpl::PostDelayedTask( 27 const tracked_objects::Location& from_here, Task* task, int64 delay_ms) { 28 return PostTaskHelper(from_here, task, delay_ms, true); 29} 30 31bool MessageLoopProxyImpl::PostNonNestableTask( 32 const tracked_objects::Location& from_here, Task* task) { 33 return PostTaskHelper(from_here, task, 0, false); 34} 35 36bool MessageLoopProxyImpl::PostNonNestableDelayedTask( 37 const tracked_objects::Location& from_here, 38 Task* task, 39 int64 delay_ms) { 40 return PostTaskHelper(from_here, task, delay_ms, false); 41} 42 43bool MessageLoopProxyImpl::BelongsToCurrentThread() { 44 // We shouldn't use MessageLoop::current() since it uses LazyInstance which 45 // may be deleted by ~AtExitManager when a WorkerPool thread calls this 46 // function. 47 // http://crbug.com/63678 48 base::ThreadRestrictions::ScopedAllowSingleton allow_singleton; 49 AutoLock lock(message_loop_lock_); 50 return (target_message_loop_ && 51 (MessageLoop::current() == target_message_loop_)); 52} 53 54// MessageLoop::DestructionObserver implementation 55void MessageLoopProxyImpl::WillDestroyCurrentMessageLoop() { 56 AutoLock lock(message_loop_lock_); 57 target_message_loop_ = NULL; 58} 59 60void MessageLoopProxyImpl::OnDestruct() const { 61 // We shouldn't use MessageLoop::current() since it uses LazyInstance which 62 // may be deleted by ~AtExitManager when a WorkerPool thread calls this 63 // function. 64 // http://crbug.com/63678 65 base::ThreadRestrictions::ScopedAllowSingleton allow_singleton; 66 bool delete_later = false; 67 { 68 AutoLock lock(message_loop_lock_); 69 if (target_message_loop_ && 70 (MessageLoop::current() != target_message_loop_)) { 71 target_message_loop_->DeleteSoon(FROM_HERE, this); 72 delete_later = true; 73 } 74 } 75 if (!delete_later) 76 delete this; 77} 78 79MessageLoopProxyImpl::MessageLoopProxyImpl() 80 : target_message_loop_(MessageLoop::current()) { 81 target_message_loop_->AddDestructionObserver(this); 82} 83 84bool MessageLoopProxyImpl::PostTaskHelper( 85 const tracked_objects::Location& from_here, Task* task, int64 delay_ms, 86 bool nestable) { 87 bool ret = false; 88 { 89 AutoLock lock(message_loop_lock_); 90 if (target_message_loop_) { 91 if (nestable) { 92 target_message_loop_->PostDelayedTask(from_here, task, delay_ms); 93 } else { 94 target_message_loop_->PostNonNestableDelayedTask(from_here, task, 95 delay_ms); 96 } 97 ret = true; 98 } 99 } 100 if (!ret) 101 delete task; 102 return ret; 103} 104 105scoped_refptr<MessageLoopProxy> 106MessageLoopProxy::CreateForCurrentThread() { 107 scoped_refptr<MessageLoopProxy> ret(new MessageLoopProxyImpl()); 108 return ret; 109} 110 111} // namespace base 112