cef/libcef/common/thread_impl.cc

154 lines
4.0 KiB
C++
Raw Normal View History

2016-11-12 00:22:53 +01:00
// Copyright 2016 The Chromium Embedded Framework 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 "cef/libcef/common/thread_impl.h"
2016-11-12 00:22:53 +01:00
#include <memory>
#include "base/functional/bind.h"
2016-11-12 00:22:53 +01:00
#include "base/threading/thread_restrictions.h"
#include "cef/libcef/common/task_runner_impl.h"
2016-11-12 00:22:53 +01:00
namespace {
void StopAndDestroy(base::Thread* thread) {
// Calling PlatformThread::Join() on the UI thread is otherwise disallowed.
base::ScopedAllowBaseSyncPrimitivesForTesting scoped_allow_sync_primitives;
2016-11-12 00:22:53 +01:00
// Deleting |thread| will implicitly stop and join it.
delete thread;
}
} // namespace
// static
CefRefPtr<CefThread> CefThread::CreateThread(
const CefString& display_name,
cef_thread_priority_t priority,
cef_message_loop_type_t message_loop_type,
bool stoppable,
cef_com_init_mode_t com_init_mode) {
if (!CefTaskRunnerImpl::GetCurrentTaskRunner()) {
DCHECK(false) << "called on invalid thread";
2016-11-12 00:22:53 +01:00
return nullptr;
}
CefRefPtr<CefThreadImpl> thread_impl = new CefThreadImpl();
if (!thread_impl->Create(display_name, priority, message_loop_type, stoppable,
com_init_mode)) {
return nullptr;
}
return thread_impl;
}
CefThreadImpl::CefThreadImpl() = default;
2016-11-12 00:22:53 +01:00
CefThreadImpl::~CefThreadImpl() {
if (thread_.get()) {
if (!owner_task_runner_->RunsTasksInCurrentSequence()) {
2016-11-12 00:22:53 +01:00
// Delete |thread_| on the correct thread.
owner_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(StopAndDestroy, base::Unretained(thread_.release())));
2016-11-12 00:22:53 +01:00
} else {
StopAndDestroy(thread_.release());
}
}
}
bool CefThreadImpl::Create(const CefString& display_name,
cef_thread_priority_t priority,
cef_message_loop_type_t message_loop_type,
bool stoppable,
cef_com_init_mode_t com_init_mode) {
owner_task_runner_ = CefTaskRunnerImpl::GetCurrentTaskRunner();
DCHECK(owner_task_runner_);
2023-01-02 23:59:03 +01:00
if (!owner_task_runner_) {
2016-11-12 00:22:53 +01:00
return false;
2023-01-02 23:59:03 +01:00
}
2016-11-12 00:22:53 +01:00
thread_ = std::make_unique<base::Thread>(display_name);
2016-11-12 00:22:53 +01:00
base::Thread::Options options;
switch (priority) {
case TP_BACKGROUND:
options.thread_type = base::ThreadType::kBackground;
2016-11-12 00:22:53 +01:00
break;
case TP_DISPLAY:
options.thread_type = base::ThreadType::kDisplayCritical;
2016-11-12 00:22:53 +01:00
break;
case TP_REALTIME_AUDIO:
options.thread_type = base::ThreadType::kRealtimeAudio;
2016-11-12 00:22:53 +01:00
break;
default:
break;
}
switch (message_loop_type) {
case ML_TYPE_UI:
options.message_pump_type = base::MessagePumpType::UI;
2016-11-12 00:22:53 +01:00
break;
case ML_TYPE_IO:
options.message_pump_type = base::MessagePumpType::IO;
2016-11-12 00:22:53 +01:00
break;
default:
break;
}
options.joinable = stoppable;
#if BUILDFLAG(IS_WIN)
2016-11-12 00:22:53 +01:00
if (com_init_mode != COM_INIT_MODE_NONE) {
2023-01-02 23:59:03 +01:00
if (com_init_mode == COM_INIT_MODE_STA) {
options.message_pump_type = base::MessagePumpType::UI;
2023-01-02 23:59:03 +01:00
}
2016-11-12 00:22:53 +01:00
thread_->init_com_with_mta(com_init_mode == COM_INIT_MODE_MTA);
}
#endif
if (!thread_->StartWithOptions(std::move(options))) {
2016-11-12 00:22:53 +01:00
thread_.reset();
return false;
}
thread_task_runner_ = new CefTaskRunnerImpl(thread_->task_runner());
thread_id_ = thread_->GetThreadId();
return true;
}
CefRefPtr<CefTaskRunner> CefThreadImpl::GetTaskRunner() {
return thread_task_runner_;
}
cef_platform_thread_id_t CefThreadImpl::GetPlatformThreadId() {
return thread_id_;
}
void CefThreadImpl::Stop() {
2023-01-02 23:59:03 +01:00
if (!owner_task_runner_) {
2016-11-12 00:22:53 +01:00
return;
2023-01-02 23:59:03 +01:00
}
if (!owner_task_runner_->RunsTasksInCurrentSequence()) {
DCHECK(false) << "called on invalid thread";
2016-11-12 00:22:53 +01:00
return;
}
2023-01-02 23:59:03 +01:00
if (thread_) {
2016-11-12 00:22:53 +01:00
StopAndDestroy(thread_.release());
2023-01-02 23:59:03 +01:00
}
2016-11-12 00:22:53 +01:00
}
bool CefThreadImpl::IsRunning() {
2023-01-02 23:59:03 +01:00
if (!owner_task_runner_) {
2016-11-12 00:22:53 +01:00
return false;
2023-01-02 23:59:03 +01:00
}
if (!owner_task_runner_->RunsTasksInCurrentSequence()) {
DCHECK(false) << "called on invalid thread";
2016-11-12 00:22:53 +01:00
return false;
}
return thread_ && thread_->IsRunning();
}