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 8 namespace base { 9 10 MessageLoopProxyImpl::~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 21 bool MessageLoopProxyImpl::PostTask(const tracked_objects::Location& from_here, 22 Task* task) { 23 return PostTaskHelper(from_here, task, 0, true); 24 } 25 26 bool 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 31 bool MessageLoopProxyImpl::PostNonNestableTask( 32 const tracked_objects::Location& from_here, Task* task) { 33 return PostTaskHelper(from_here, task, 0, false); 34 } 35 36 bool 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 43 bool 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 55 void MessageLoopProxyImpl::WillDestroyCurrentMessageLoop() { 56 AutoLock lock(message_loop_lock_); 57 target_message_loop_ = NULL; 58 } 59 60 void 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 79 MessageLoopProxyImpl::MessageLoopProxyImpl() 80 : target_message_loop_(MessageLoop::current()) { 81 target_message_loop_->AddDestructionObserver(this); 82 } 83 84 bool 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 105 scoped_refptr<MessageLoopProxy> 106 MessageLoopProxy::CreateForCurrentThread() { 107 scoped_refptr<MessageLoopProxy> ret(new MessageLoopProxyImpl()); 108 return ret; 109 } 110 111 } // namespace base 112