mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Add CefThread interface (issue #1632)
This commit is contained in:
148
libcef/common/thread_impl.cc
Normal file
148
libcef/common/thread_impl.cc
Normal file
@@ -0,0 +1,148 @@
|
||||
// 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 "libcef/common/thread_impl.h"
|
||||
|
||||
#include "libcef/common/task_runner_impl.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void StopAndDestroy(base::Thread* thread) {
|
||||
// Calling PlatformThread::Join() on the UI thread is otherwise disallowed.
|
||||
base::ThreadRestrictions::ScopedAllowIO scoped_allow_io;
|
||||
|
||||
// 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 (!base::MessageLoop::current()) {
|
||||
NOTREACHED() << "called on invalid thread";
|
||||
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()
|
||||
: thread_id_(kInvalidPlatformThreadId) {
|
||||
}
|
||||
|
||||
CefThreadImpl::~CefThreadImpl() {
|
||||
if (thread_.get()) {
|
||||
if (!owner_task_runner_->RunsTasksOnCurrentThread()) {
|
||||
// Delete |thread_| on the correct thread.
|
||||
owner_task_runner_->PostTask(FROM_HERE,
|
||||
base::Bind(StopAndDestroy, base::Unretained(thread_.release())));
|
||||
} 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_);
|
||||
if (!owner_task_runner_)
|
||||
return false;
|
||||
|
||||
thread_.reset(new base::Thread(display_name));
|
||||
|
||||
base::Thread::Options options;
|
||||
|
||||
switch (priority) {
|
||||
case TP_BACKGROUND:
|
||||
options.priority = base::ThreadPriority::BACKGROUND;
|
||||
break;
|
||||
case TP_DISPLAY:
|
||||
options.priority = base::ThreadPriority::DISPLAY;
|
||||
break;
|
||||
case TP_REALTIME_AUDIO:
|
||||
options.priority = base::ThreadPriority::REALTIME_AUDIO;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (message_loop_type) {
|
||||
case ML_TYPE_UI:
|
||||
options.message_loop_type = base::MessageLoop::TYPE_UI;
|
||||
break;
|
||||
case ML_TYPE_IO:
|
||||
options.message_loop_type = base::MessageLoop::TYPE_IO;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
options.joinable = stoppable;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
if (com_init_mode != COM_INIT_MODE_NONE) {
|
||||
if (com_init_mode == COM_INIT_MODE_STA)
|
||||
options.message_loop_type = base::MessageLoop::TYPE_UI;
|
||||
thread_->init_com_with_mta(com_init_mode == COM_INIT_MODE_MTA);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!thread_->StartWithOptions(options)) {
|
||||
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() {
|
||||
if (!owner_task_runner_)
|
||||
return;
|
||||
if (!owner_task_runner_->RunsTasksOnCurrentThread()) {
|
||||
NOTREACHED() << "called on invalid thread";
|
||||
return;
|
||||
}
|
||||
|
||||
if (thread_)
|
||||
StopAndDestroy(thread_.release());
|
||||
}
|
||||
|
||||
bool CefThreadImpl::IsRunning() {
|
||||
if (!owner_task_runner_)
|
||||
return false;
|
||||
if (!owner_task_runner_->RunsTasksOnCurrentThread()) {
|
||||
NOTREACHED() << "called on invalid thread";
|
||||
return false;
|
||||
}
|
||||
|
||||
return thread_ && thread_->IsRunning();
|
||||
}
|
Reference in New Issue
Block a user