mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			148 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // 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::ScopedAllowBaseSyncPrimitivesForTesting scoped_allow_sync_primitives;
 | |
| 
 | |
|   // 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()) {
 | |
|     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_->RunsTasksInCurrentSequence()) {
 | |
|       // 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_pump_type = base::MessagePumpType::UI;
 | |
|       break;
 | |
|     case ML_TYPE_IO:
 | |
|       options.message_pump_type = base::MessagePumpType::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_pump_type = base::MessagePumpType::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_->RunsTasksInCurrentSequence()) {
 | |
|     NOTREACHED() << "called on invalid thread";
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if (thread_)
 | |
|     StopAndDestroy(thread_.release());
 | |
| }
 | |
| 
 | |
| bool CefThreadImpl::IsRunning() {
 | |
|   if (!owner_task_runner_)
 | |
|     return false;
 | |
|   if (!owner_task_runner_->RunsTasksInCurrentSequence()) {
 | |
|     NOTREACHED() << "called on invalid thread";
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   return thread_ && thread_->IsRunning();
 | |
| }
 |