// Copyright (c) 2013 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/task_runner_impl.h" #include "libcef/common/content_client.h" #include "libcef/renderer/content_renderer_client.h" #include "base/bind.h" #include "base/location.h" #include "base/logging.h" #include "base/message_loop/message_loop.h" #include "base/threading/thread_task_runner_handle.h" #include "content/public/browser/browser_thread.h" using content::BrowserThread; // CefTaskRunner // static CefRefPtr CefTaskRunner::GetForCurrentThread() { scoped_refptr task_runner = CefTaskRunnerImpl::GetCurrentTaskRunner(); if (task_runner.get()) return new CefTaskRunnerImpl(task_runner); return NULL; } // static CefRefPtr CefTaskRunner::GetForThread(CefThreadId threadId) { scoped_refptr task_runner = CefTaskRunnerImpl::GetTaskRunner(threadId); if (task_runner.get()) return new CefTaskRunnerImpl(task_runner); LOG(WARNING) << "Invalid thread id " << threadId; return NULL; } // CefTaskRunnerImpl CefTaskRunnerImpl::CefTaskRunnerImpl( scoped_refptr task_runner) : task_runner_(task_runner) { DCHECK(task_runner_.get()); } // static scoped_refptr CefTaskRunnerImpl::GetTaskRunner(CefThreadId threadId) { // Render process. if (threadId == TID_RENDERER) { CefContentRendererClient* client = CefContentRendererClient::Get(); if (client) return client->render_task_runner(); return NULL; } // Browser process. int id = -1; switch (threadId) { case TID_UI: id = BrowserThread::UI; break; case TID_DB: id = BrowserThread::DB; break; case TID_FILE: id = BrowserThread::FILE; break; case TID_FILE_USER_BLOCKING: id = BrowserThread::FILE_USER_BLOCKING; break; case TID_PROCESS_LAUNCHER: id = BrowserThread::PROCESS_LAUNCHER; break; case TID_CACHE: id = BrowserThread::CACHE; break; case TID_IO: id = BrowserThread::IO; break; default: break; }; if (id >= 0 && CefContentClient::Get() && CefContentClient::Get()->browser() && BrowserThread::IsMessageLoopValid(static_cast(id))) { // Don't use BrowserThread::GetTaskRunnerForThread because it returns // a new MessageLoopProxy object for each call and makes pointer equality // testing impossible. base::MessageLoop* message_loop = BrowserThread::UnsafeGetMessageLoopForThread( static_cast(id)); if (message_loop) return message_loop->task_runner(); } return NULL; } // static scoped_refptr CefTaskRunnerImpl::GetCurrentTaskRunner() { scoped_refptr task_runner; // Check for a MessageLoopProxy. This covers all of the named browser and // render process threads, plus a few extra. task_runner = base::ThreadTaskRunnerHandle::Get(); if (!task_runner.get()) { // Check for a WebWorker thread. CefContentRendererClient* client = CefContentRendererClient::Get(); if (client) task_runner = client->GetCurrentTaskRunner(); } return task_runner; } bool CefTaskRunnerImpl::IsSame(CefRefPtr that) { CefTaskRunnerImpl* impl = static_cast(that.get()); return (impl && task_runner_ == impl->task_runner_); } bool CefTaskRunnerImpl::BelongsToCurrentThread() { return task_runner_->RunsTasksOnCurrentThread(); } bool CefTaskRunnerImpl::BelongsToThread(CefThreadId threadId) { scoped_refptr task_runner = GetTaskRunner(threadId); return (task_runner_ == task_runner); } bool CefTaskRunnerImpl::PostTask(CefRefPtr task) { return task_runner_->PostTask(FROM_HERE, base::Bind(&CefTask::Execute, task.get())); } bool CefTaskRunnerImpl::PostDelayedTask(CefRefPtr task, int64 delay_ms) { return task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&CefTask::Execute, task.get()), base::TimeDelta::FromMilliseconds(delay_ms)); }