nim_duilib/base/framework/message_loop_proxy.cpp

120 lines
2.6 KiB
C++
Raw Normal View History

2019-04-19 17:19:57 +08:00
// 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> 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