2016-11-11 18:22:53 -05: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.
|
|
|
|
|
2024-04-30 11:45:07 -04:00
|
|
|
#include "cef/libcef/common/thread_impl.h"
|
2016-11-11 18:22:53 -05:00
|
|
|
|
2024-01-20 17:48:57 -05:00
|
|
|
#include <memory>
|
|
|
|
|
2023-01-30 12:43:54 -05:00
|
|
|
#include "base/functional/bind.h"
|
2016-11-11 18:22:53 -05:00
|
|
|
#include "base/threading/thread_restrictions.h"
|
2024-04-30 11:45:07 -04:00
|
|
|
#include "cef/libcef/common/task_runner_impl.h"
|
2016-11-11 18:22:53 -05:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
void StopAndDestroy(base::Thread* thread) {
|
|
|
|
// Calling PlatformThread::Join() on the UI thread is otherwise disallowed.
|
2019-01-17 10:56:52 +01:00
|
|
|
base::ScopedAllowBaseSyncPrimitivesForTesting scoped_allow_sync_primitives;
|
2016-11-11 18:22:53 -05: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) {
|
2017-07-26 19:19:27 -04:00
|
|
|
if (!CefTaskRunnerImpl::GetCurrentTaskRunner()) {
|
2023-05-08 18:07:57 +03:00
|
|
|
DCHECK(false) << "called on invalid thread";
|
2016-11-11 18:22:53 -05: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;
|
|
|
|
}
|
|
|
|
|
2024-01-20 17:48:57 -05:00
|
|
|
CefThreadImpl::CefThreadImpl() = default;
|
2016-11-11 18:22:53 -05:00
|
|
|
|
|
|
|
CefThreadImpl::~CefThreadImpl() {
|
|
|
|
if (thread_.get()) {
|
2017-09-06 17:40:58 -04:00
|
|
|
if (!owner_task_runner_->RunsTasksInCurrentSequence()) {
|
2016-11-11 18:22:53 -05:00
|
|
|
// Delete |thread_| on the correct thread.
|
2017-05-17 11:29:28 +02:00
|
|
|
owner_task_runner_->PostTask(
|
|
|
|
FROM_HERE,
|
2021-06-03 21:34:56 -04:00
|
|
|
base::BindOnce(StopAndDestroy, base::Unretained(thread_.release())));
|
2016-11-11 18:22:53 -05: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 17:59:03 -05:00
|
|
|
if (!owner_task_runner_) {
|
2016-11-11 18:22:53 -05:00
|
|
|
return false;
|
2023-01-02 17:59:03 -05:00
|
|
|
}
|
2016-11-11 18:22:53 -05:00
|
|
|
|
2024-01-20 17:48:57 -05:00
|
|
|
thread_ = std::make_unique<base::Thread>(display_name);
|
2016-11-11 18:22:53 -05:00
|
|
|
|
|
|
|
base::Thread::Options options;
|
|
|
|
|
|
|
|
switch (priority) {
|
|
|
|
case TP_BACKGROUND:
|
2022-07-21 13:26:10 -04:00
|
|
|
options.thread_type = base::ThreadType::kBackground;
|
2016-11-11 18:22:53 -05:00
|
|
|
break;
|
|
|
|
case TP_DISPLAY:
|
2022-07-21 13:26:10 -04:00
|
|
|
options.thread_type = base::ThreadType::kDisplayCritical;
|
2016-11-11 18:22:53 -05:00
|
|
|
break;
|
|
|
|
case TP_REALTIME_AUDIO:
|
2022-07-21 13:26:10 -04:00
|
|
|
options.thread_type = base::ThreadType::kRealtimeAudio;
|
2016-11-11 18:22:53 -05:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (message_loop_type) {
|
|
|
|
case ML_TYPE_UI:
|
2019-10-01 13:55:16 +00:00
|
|
|
options.message_pump_type = base::MessagePumpType::UI;
|
2016-11-11 18:22:53 -05:00
|
|
|
break;
|
|
|
|
case ML_TYPE_IO:
|
2019-10-01 13:55:16 +00:00
|
|
|
options.message_pump_type = base::MessagePumpType::IO;
|
2016-11-11 18:22:53 -05:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
options.joinable = stoppable;
|
|
|
|
|
2022-01-24 12:58:02 -05:00
|
|
|
#if BUILDFLAG(IS_WIN)
|
2016-11-11 18:22:53 -05:00
|
|
|
if (com_init_mode != COM_INIT_MODE_NONE) {
|
2023-01-02 17:59:03 -05:00
|
|
|
if (com_init_mode == COM_INIT_MODE_STA) {
|
2019-10-01 13:55:16 +00:00
|
|
|
options.message_pump_type = base::MessagePumpType::UI;
|
2023-01-02 17:59:03 -05:00
|
|
|
}
|
2016-11-11 18:22:53 -05:00
|
|
|
thread_->init_com_with_mta(com_init_mode == COM_INIT_MODE_MTA);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-07-23 12:40:13 -04:00
|
|
|
if (!thread_->StartWithOptions(std::move(options))) {
|
2016-11-11 18:22:53 -05: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 17:59:03 -05:00
|
|
|
if (!owner_task_runner_) {
|
2016-11-11 18:22:53 -05:00
|
|
|
return;
|
2023-01-02 17:59:03 -05:00
|
|
|
}
|
2017-09-06 17:40:58 -04:00
|
|
|
if (!owner_task_runner_->RunsTasksInCurrentSequence()) {
|
2023-05-08 18:07:57 +03:00
|
|
|
DCHECK(false) << "called on invalid thread";
|
2016-11-11 18:22:53 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-01-02 17:59:03 -05:00
|
|
|
if (thread_) {
|
2016-11-11 18:22:53 -05:00
|
|
|
StopAndDestroy(thread_.release());
|
2023-01-02 17:59:03 -05:00
|
|
|
}
|
2016-11-11 18:22:53 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CefThreadImpl::IsRunning() {
|
2023-01-02 17:59:03 -05:00
|
|
|
if (!owner_task_runner_) {
|
2016-11-11 18:22:53 -05:00
|
|
|
return false;
|
2023-01-02 17:59:03 -05:00
|
|
|
}
|
2017-09-06 17:40:58 -04:00
|
|
|
if (!owner_task_runner_->RunsTasksInCurrentSequence()) {
|
2023-05-08 18:07:57 +03:00
|
|
|
DCHECK(false) << "called on invalid thread";
|
2016-11-11 18:22:53 -05:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return thread_ && thread_->IsRunning();
|
|
|
|
}
|