Home | History | Annotate | Download | only in base
      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