mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-28 08:16:09 +03:00
253 lines
7.9 KiB
C++
253 lines
7.9 KiB
C++
|
// Copyright 2018 The Chromium Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style license that can be
|
||
|
// found in the LICENSE file.
|
||
|
|
||
|
#include "base/message_loop/message_loop_current.h"
|
||
|
|
||
|
#include "base/bind.h"
|
||
|
#include "base/message_loop/message_loop.h"
|
||
|
#include "base/message_loop/message_pump_for_io.h"
|
||
|
#include "base/message_loop/message_pump_for_ui.h"
|
||
|
#include "base/no_destructor.h"
|
||
|
#include "base/threading/thread_local.h"
|
||
|
|
||
|
namespace base {
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
base::ThreadLocalPointer<MessageLoop>* GetTLSMessageLoop() {
|
||
|
static NoDestructor<ThreadLocalPointer<MessageLoop>> lazy_tls_ptr;
|
||
|
return lazy_tls_ptr.get();
|
||
|
}
|
||
|
|
||
|
} // namespace
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// MessageLoopCurrent
|
||
|
|
||
|
// static
|
||
|
MessageLoopCurrent MessageLoopCurrent::Get() {
|
||
|
return MessageLoopCurrent(GetTLSMessageLoop()->Get());
|
||
|
}
|
||
|
|
||
|
// static
|
||
|
bool MessageLoopCurrent::IsSet() {
|
||
|
return !!GetTLSMessageLoop()->Get();
|
||
|
}
|
||
|
|
||
|
void MessageLoopCurrent::AddDestructionObserver(
|
||
|
DestructionObserver* destruction_observer) {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(current_->bound_thread_checker_);
|
||
|
current_->destruction_observers_.AddObserver(destruction_observer);
|
||
|
}
|
||
|
|
||
|
void MessageLoopCurrent::RemoveDestructionObserver(
|
||
|
DestructionObserver* destruction_observer) {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(current_->bound_thread_checker_);
|
||
|
current_->destruction_observers_.RemoveObserver(destruction_observer);
|
||
|
}
|
||
|
|
||
|
const scoped_refptr<SingleThreadTaskRunner>& MessageLoopCurrent::task_runner()
|
||
|
const {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(current_->bound_thread_checker_);
|
||
|
return current_->task_runner();
|
||
|
}
|
||
|
|
||
|
void MessageLoopCurrent::SetTaskRunner(
|
||
|
scoped_refptr<SingleThreadTaskRunner> task_runner) {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(current_->bound_thread_checker_);
|
||
|
current_->SetTaskRunner(std::move(task_runner));
|
||
|
}
|
||
|
|
||
|
bool MessageLoopCurrent::IsIdleForTesting() {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(current_->bound_thread_checker_);
|
||
|
return current_->IsIdleForTesting();
|
||
|
}
|
||
|
|
||
|
void MessageLoopCurrent::AddTaskObserver(TaskObserver* task_observer) {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(current_->bound_thread_checker_);
|
||
|
current_->AddTaskObserver(task_observer);
|
||
|
}
|
||
|
|
||
|
void MessageLoopCurrent::RemoveTaskObserver(TaskObserver* task_observer) {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(current_->bound_thread_checker_);
|
||
|
current_->RemoveTaskObserver(task_observer);
|
||
|
}
|
||
|
|
||
|
void MessageLoopCurrent::SetNestableTasksAllowed(bool allowed) {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(current_->bound_thread_checker_);
|
||
|
if (allowed) {
|
||
|
// Kick the native pump just in case we enter a OS-driven nested message
|
||
|
// loop that does not go through RunLoop::Run().
|
||
|
current_->pump_->ScheduleWork();
|
||
|
}
|
||
|
current_->task_execution_allowed_ = allowed;
|
||
|
}
|
||
|
|
||
|
bool MessageLoopCurrent::NestableTasksAllowed() const {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(current_->bound_thread_checker_);
|
||
|
return current_->task_execution_allowed_;
|
||
|
}
|
||
|
|
||
|
MessageLoopCurrent::ScopedNestableTaskAllower::ScopedNestableTaskAllower()
|
||
|
: loop_(GetTLSMessageLoop()->Get()),
|
||
|
old_state_(loop_->NestableTasksAllowed()) {
|
||
|
loop_->SetNestableTasksAllowed(true);
|
||
|
}
|
||
|
|
||
|
MessageLoopCurrent::ScopedNestableTaskAllower::~ScopedNestableTaskAllower() {
|
||
|
loop_->SetNestableTasksAllowed(old_state_);
|
||
|
}
|
||
|
|
||
|
// static
|
||
|
void MessageLoopCurrent::BindToCurrentThreadInternal(MessageLoop* current) {
|
||
|
DCHECK(!GetTLSMessageLoop()->Get())
|
||
|
<< "Can't register a second MessageLoop on the same thread.";
|
||
|
GetTLSMessageLoop()->Set(current);
|
||
|
}
|
||
|
|
||
|
// static
|
||
|
void MessageLoopCurrent::UnbindFromCurrentThreadInternal(MessageLoop* current) {
|
||
|
DCHECK_EQ(current, GetTLSMessageLoop()->Get());
|
||
|
GetTLSMessageLoop()->Set(nullptr);
|
||
|
}
|
||
|
|
||
|
bool MessageLoopCurrent::IsBoundToCurrentThreadInternal(
|
||
|
MessageLoop* message_loop) {
|
||
|
return GetTLSMessageLoop()->Get() == message_loop;
|
||
|
}
|
||
|
|
||
|
#if !defined(OS_NACL)
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// MessageLoopCurrentForUI
|
||
|
|
||
|
// static
|
||
|
MessageLoopCurrentForUI MessageLoopCurrentForUI::Get() {
|
||
|
MessageLoop* loop = GetTLSMessageLoop()->Get();
|
||
|
DCHECK(loop);
|
||
|
#if defined(OS_ANDROID)
|
||
|
DCHECK(loop->IsType(MessageLoop::TYPE_UI) ||
|
||
|
loop->IsType(MessageLoop::TYPE_JAVA));
|
||
|
#else // defined(OS_ANDROID)
|
||
|
DCHECK(loop->IsType(MessageLoop::TYPE_UI));
|
||
|
#endif // defined(OS_ANDROID)
|
||
|
auto* loop_for_ui = static_cast<MessageLoopForUI*>(loop);
|
||
|
return MessageLoopCurrentForUI(
|
||
|
loop_for_ui, static_cast<MessagePumpForUI*>(loop_for_ui->pump_.get()));
|
||
|
}
|
||
|
|
||
|
// static
|
||
|
bool MessageLoopCurrentForUI::IsSet() {
|
||
|
MessageLoop* loop = GetTLSMessageLoop()->Get();
|
||
|
return loop &&
|
||
|
#if defined(OS_ANDROID)
|
||
|
(loop->IsType(MessageLoop::TYPE_UI) ||
|
||
|
loop->IsType(MessageLoop::TYPE_JAVA));
|
||
|
#else // defined(OS_ANDROID)
|
||
|
loop->IsType(MessageLoop::TYPE_UI);
|
||
|
#endif // defined(OS_ANDROID)
|
||
|
}
|
||
|
|
||
|
#if defined(USE_OZONE) && !defined(OS_FUCHSIA) && !defined(OS_WIN)
|
||
|
bool MessageLoopCurrentForUI::WatchFileDescriptor(
|
||
|
int fd,
|
||
|
bool persistent,
|
||
|
MessagePumpForUI::Mode mode,
|
||
|
MessagePumpForUI::FdWatchController* controller,
|
||
|
MessagePumpForUI::FdWatcher* delegate) {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(current_->bound_thread_checker_);
|
||
|
return pump_->WatchFileDescriptor(fd, persistent, mode, controller, delegate);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if defined(OS_IOS)
|
||
|
void MessageLoopCurrentForUI::Attach() {
|
||
|
static_cast<MessageLoopForUI*>(current_)->Attach();
|
||
|
}
|
||
|
#endif // defined(OS_IOS)
|
||
|
|
||
|
#if defined(OS_ANDROID)
|
||
|
void MessageLoopCurrentForUI::Start() {
|
||
|
static_cast<MessageLoopForUI*>(current_)->Start();
|
||
|
}
|
||
|
|
||
|
void MessageLoopCurrentForUI::Abort() {
|
||
|
static_cast<MessageLoopForUI*>(current_)->Abort();
|
||
|
}
|
||
|
#endif // defined(OS_ANDROID)
|
||
|
|
||
|
#endif // !defined(OS_NACL)
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// MessageLoopCurrentForIO
|
||
|
|
||
|
// static
|
||
|
MessageLoopCurrentForIO MessageLoopCurrentForIO::Get() {
|
||
|
MessageLoop* loop = GetTLSMessageLoop()->Get();
|
||
|
DCHECK(loop);
|
||
|
DCHECK_EQ(MessageLoop::TYPE_IO, loop->type());
|
||
|
auto* loop_for_io = static_cast<MessageLoopForIO*>(loop);
|
||
|
return MessageLoopCurrentForIO(
|
||
|
loop_for_io, static_cast<MessagePumpForIO*>(loop_for_io->pump_.get()));
|
||
|
}
|
||
|
|
||
|
// static
|
||
|
bool MessageLoopCurrentForIO::IsSet() {
|
||
|
MessageLoop* loop = GetTLSMessageLoop()->Get();
|
||
|
return loop && loop->IsType(MessageLoop::TYPE_IO);
|
||
|
}
|
||
|
|
||
|
#if !defined(OS_NACL_SFI)
|
||
|
|
||
|
#if defined(OS_WIN)
|
||
|
void MessageLoopCurrentForIO::RegisterIOHandler(
|
||
|
HANDLE file,
|
||
|
MessagePumpForIO::IOHandler* handler) {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(current_->bound_thread_checker_);
|
||
|
pump_->RegisterIOHandler(file, handler);
|
||
|
}
|
||
|
|
||
|
bool MessageLoopCurrentForIO::RegisterJobObject(
|
||
|
HANDLE job,
|
||
|
MessagePumpForIO::IOHandler* handler) {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(current_->bound_thread_checker_);
|
||
|
return pump_->RegisterJobObject(job, handler);
|
||
|
}
|
||
|
|
||
|
bool MessageLoopCurrentForIO::WaitForIOCompletion(
|
||
|
DWORD timeout,
|
||
|
MessagePumpForIO::IOHandler* filter) {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(current_->bound_thread_checker_);
|
||
|
return pump_->WaitForIOCompletion(timeout, filter);
|
||
|
}
|
||
|
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
|
||
|
bool MessageLoopCurrentForIO::WatchFileDescriptor(
|
||
|
int fd,
|
||
|
bool persistent,
|
||
|
MessagePumpForIO::Mode mode,
|
||
|
MessagePumpForIO::FdWatchController* controller,
|
||
|
MessagePumpForIO::FdWatcher* delegate) {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(current_->bound_thread_checker_);
|
||
|
return pump_->WatchFileDescriptor(fd, persistent, mode, controller, delegate);
|
||
|
}
|
||
|
#endif // defined(OS_WIN)
|
||
|
|
||
|
#endif // !defined(OS_NACL_SFI)
|
||
|
|
||
|
#if defined(OS_FUCHSIA)
|
||
|
// Additional watch API for native platform resources.
|
||
|
bool MessageLoopCurrentForIO::WatchZxHandle(
|
||
|
zx_handle_t handle,
|
||
|
bool persistent,
|
||
|
zx_signals_t signals,
|
||
|
MessagePumpForIO::ZxHandleWatchController* controller,
|
||
|
MessagePumpForIO::ZxHandleWatcher* delegate) {
|
||
|
DCHECK_CALLED_ON_VALID_THREAD(current_->bound_thread_checker_);
|
||
|
return pump_->WatchZxHandle(handle, persistent, signals, controller,
|
||
|
delegate);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
} // namespace base
|