// Copyright (c) 2013, NetEase Inc. All rights reserved. // // Author: wrt(guangguang) // Date: 2013/08/26 // // This file trys to implement a cross flatform message loop proxy, // the mechanism of which is from the Google Chrome project. #include "base/framework/message_loop_proxy.h" #include "base/synchronization/lock.h" namespace nbase { MessageLoopProxy::~MessageLoopProxy() { } bool MessageLoopProxy::PostTask(const StdClosure &task) { return PostTaskHelper(task, TimeDelta(), true); } bool MessageLoopProxy::PostDelayedTask( const StdClosure& task, TimeDelta delay) { return PostTaskHelper(task, delay, true); } bool MessageLoopProxy::PostNonNestableTask(const StdClosure &task) { return PostTaskHelper(task, TimeDelta(), false); } bool MessageLoopProxy::PostNonNestableDelayedTask( const StdClosure& task, TimeDelta delay) { return PostTaskHelper(task, delay, false); } bool MessageLoopProxy::BelongsToCurrentThread() const { NAutoLock lock(&message_loop_lock_); return (target_message_loop_ && (MessageLoop::current() == target_message_loop_)); } // MessageLoop::DestructionObserver implementation void MessageLoopProxy::WillDestroyCurrentMessageLoop() { NAutoLock lock(&message_loop_lock_); target_message_loop_ = nullptr; } void MessageLoopProxy::OnDestruct() const { bool delete_later = false; { NAutoLock lock(&message_loop_lock_); if (target_message_loop_ && (MessageLoop::current() != target_message_loop_)) { target_message_loop_->PostNonNestableTask( nbase::Bind(&MessageLoopProxy::DeleteSelf, this)); delete_later = true; } } if (!delete_later) delete this; } void MessageLoopProxy::DeleteSelf() const { delete this; } MessageLoopProxy::MessageLoopProxy() : target_message_loop_(MessageLoop::current()) { } bool MessageLoopProxy::PostTaskHelper( const StdClosure& task, TimeDelta delay, bool nestable) { NAutoLock lock(&message_loop_lock_); if (target_message_loop_) { if (nestable) { if (delay == TimeDelta()) target_message_loop_->PostTask(task); else target_message_loop_->PostDelayedTask(task, delay); } else { if (delay == TimeDelta()) target_message_loop_->PostNonNestableTask(task); else target_message_loop_->PostNonNestableDelayedTask(task, delay); } return true; } return false; } std::shared_ptr MessageLoopProxy::current() { MessageLoop* cur_loop = MessageLoop::current(); if (!cur_loop) return nullptr; return cur_loop->message_loop_proxy(); } void MessageLoopProxyTraits::Destruct(const MessageLoopProxy* proxy) { proxy->OnDestruct(); } } // namespace nbase