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:
4
BUILD.gn
4
BUILD.gn
@ -463,6 +463,8 @@ static_library("libcef_static") {
|
|||||||
"libcef/common/task_runner_impl.cc",
|
"libcef/common/task_runner_impl.cc",
|
||||||
"libcef/common/task_runner_impl.h",
|
"libcef/common/task_runner_impl.h",
|
||||||
"libcef/common/test/translator_test_impl.cc",
|
"libcef/common/test/translator_test_impl.cc",
|
||||||
|
"libcef/common/thread_impl.cc",
|
||||||
|
"libcef/common/thread_impl.h",
|
||||||
"libcef/common/time_impl.cc",
|
"libcef/common/time_impl.cc",
|
||||||
"libcef/common/time_util.h",
|
"libcef/common/time_util.h",
|
||||||
"libcef/common/tracker.cc",
|
"libcef/common/tracker.cc",
|
||||||
@ -1405,6 +1407,7 @@ cef_unittests_sources = [
|
|||||||
"tests/unittests/test_util.h",
|
"tests/unittests/test_util.h",
|
||||||
"tests/unittests/thread_helper.cc",
|
"tests/unittests/thread_helper.cc",
|
||||||
"tests/unittests/thread_helper.h",
|
"tests/unittests/thread_helper.h",
|
||||||
|
"tests/unittests/thread_unittest.cc",
|
||||||
"tests/unittests/tracing_unittest.cc",
|
"tests/unittests/tracing_unittest.cc",
|
||||||
"tests/unittests/translator_unittest.cc",
|
"tests/unittests/translator_unittest.cc",
|
||||||
"tests/unittests/urlrequest_unittest.cc",
|
"tests/unittests/urlrequest_unittest.cc",
|
||||||
@ -1710,6 +1713,7 @@ if (is_mac) {
|
|||||||
"tests/unittests/test_util.h",
|
"tests/unittests/test_util.h",
|
||||||
"tests/unittests/thread_helper.cc",
|
"tests/unittests/thread_helper.cc",
|
||||||
"tests/unittests/thread_helper.h",
|
"tests/unittests/thread_helper.h",
|
||||||
|
"tests/unittests/thread_unittest.cc",
|
||||||
"tests/unittests/tracing_unittest.cc",
|
"tests/unittests/tracing_unittest.cc",
|
||||||
"tests/unittests/v8_unittest.cc",
|
"tests/unittests/v8_unittest.cc",
|
||||||
]
|
]
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
'include/cef_stream.h',
|
'include/cef_stream.h',
|
||||||
'include/cef_string_visitor.h',
|
'include/cef_string_visitor.h',
|
||||||
'include/cef_task.h',
|
'include/cef_task.h',
|
||||||
|
'include/cef_thread.h',
|
||||||
'include/cef_trace.h',
|
'include/cef_trace.h',
|
||||||
'include/cef_urlrequest.h',
|
'include/cef_urlrequest.h',
|
||||||
'include/cef_v8.h',
|
'include/cef_v8.h',
|
||||||
@ -149,6 +150,7 @@
|
|||||||
'include/capi/cef_stream_capi.h',
|
'include/capi/cef_stream_capi.h',
|
||||||
'include/capi/cef_string_visitor_capi.h',
|
'include/capi/cef_string_visitor_capi.h',
|
||||||
'include/capi/cef_task_capi.h',
|
'include/capi/cef_task_capi.h',
|
||||||
|
'include/capi/cef_thread_capi.h',
|
||||||
'include/capi/cef_trace_capi.h',
|
'include/capi/cef_trace_capi.h',
|
||||||
'include/capi/cef_urlrequest_capi.h',
|
'include/capi/cef_urlrequest_capi.h',
|
||||||
'include/capi/cef_v8_capi.h',
|
'include/capi/cef_v8_capi.h',
|
||||||
@ -378,6 +380,8 @@
|
|||||||
'libcef_dll/cpptoc/views/textfield_cpptoc.h',
|
'libcef_dll/cpptoc/views/textfield_cpptoc.h',
|
||||||
'libcef_dll/ctocpp/views/textfield_delegate_ctocpp.cc',
|
'libcef_dll/ctocpp/views/textfield_delegate_ctocpp.cc',
|
||||||
'libcef_dll/ctocpp/views/textfield_delegate_ctocpp.h',
|
'libcef_dll/ctocpp/views/textfield_delegate_ctocpp.h',
|
||||||
|
'libcef_dll/cpptoc/thread_cpptoc.cc',
|
||||||
|
'libcef_dll/cpptoc/thread_cpptoc.h',
|
||||||
'libcef_dll/cpptoc/test/translator_test_cpptoc.cc',
|
'libcef_dll/cpptoc/test/translator_test_cpptoc.cc',
|
||||||
'libcef_dll/cpptoc/test/translator_test_cpptoc.h',
|
'libcef_dll/cpptoc/test/translator_test_cpptoc.h',
|
||||||
'libcef_dll/ctocpp/test/translator_test_handler_ctocpp.cc',
|
'libcef_dll/ctocpp/test/translator_test_handler_ctocpp.cc',
|
||||||
@ -636,6 +640,8 @@
|
|||||||
'libcef_dll/ctocpp/views/textfield_ctocpp.h',
|
'libcef_dll/ctocpp/views/textfield_ctocpp.h',
|
||||||
'libcef_dll/cpptoc/views/textfield_delegate_cpptoc.cc',
|
'libcef_dll/cpptoc/views/textfield_delegate_cpptoc.cc',
|
||||||
'libcef_dll/cpptoc/views/textfield_delegate_cpptoc.h',
|
'libcef_dll/cpptoc/views/textfield_delegate_cpptoc.h',
|
||||||
|
'libcef_dll/ctocpp/thread_ctocpp.cc',
|
||||||
|
'libcef_dll/ctocpp/thread_ctocpp.h',
|
||||||
'libcef_dll/ctocpp/test/translator_test_ctocpp.cc',
|
'libcef_dll/ctocpp/test/translator_test_ctocpp.cc',
|
||||||
'libcef_dll/ctocpp/test/translator_test_ctocpp.h',
|
'libcef_dll/ctocpp/test/translator_test_ctocpp.h',
|
||||||
'libcef_dll/cpptoc/test/translator_test_handler_cpptoc.cc',
|
'libcef_dll/cpptoc/test/translator_test_handler_cpptoc.cc',
|
||||||
|
115
include/capi/cef_thread_capi.h
Normal file
115
include/capi/cef_thread_capi.h
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// Copyright (c) 2016 Marshall A. Greenblatt. All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the name Chromium Embedded
|
||||||
|
// Framework nor the names of its contributors may be used to endorse
|
||||||
|
// or promote products derived from this software without specific prior
|
||||||
|
// written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file was generated by the CEF translator tool and should not edited
|
||||||
|
// by hand. See the translator.README.txt file in the tools directory for
|
||||||
|
// more information.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CEF_INCLUDE_CAPI_CEF_THREAD_CAPI_H_
|
||||||
|
#define CEF_INCLUDE_CAPI_CEF_THREAD_CAPI_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/capi/cef_task_capi.h"
|
||||||
|
#include "include/internal/cef_thread_internal.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
// A simple thread abstraction that establishes a message loop on a new thread.
|
||||||
|
// The consumer uses cef_task_tRunner to execute code on the thread's message
|
||||||
|
// loop. The thread is terminated when the cef_thread_t object is destroyed or
|
||||||
|
// stop() is called. All pending tasks queued on the thread's message loop will
|
||||||
|
// run to completion before the thread is terminated. cef_thread_create() can be
|
||||||
|
// called on any valid CEF thread in either the browser or render process. This
|
||||||
|
// structure should only be used for tasks that require a dedicated thread. In
|
||||||
|
// most cases you can post tasks to an existing CEF thread instead of creating a
|
||||||
|
// new one; see cef_task.h for details.
|
||||||
|
///
|
||||||
|
typedef struct _cef_thread_t {
|
||||||
|
///
|
||||||
|
// Base structure.
|
||||||
|
///
|
||||||
|
cef_base_t base;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns the cef_task_tRunner that will execute code on this thread's
|
||||||
|
// message loop. This function is safe to call from any thread.
|
||||||
|
///
|
||||||
|
struct _cef_task_runner_t* (CEF_CALLBACK *get_task_runner)(
|
||||||
|
struct _cef_thread_t* self);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns the platform thread ID. It will return the same value after stop()
|
||||||
|
// is called. This function is safe to call from any thread.
|
||||||
|
///
|
||||||
|
cef_platform_thread_id_t (CEF_CALLBACK *get_platform_thread_id)(
|
||||||
|
struct _cef_thread_t* self);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Stop and join the thread. This function must be called from the same thread
|
||||||
|
// that called cef_thread_create(). Do not call this function if
|
||||||
|
// cef_thread_create() was called with a |stoppable| value of false (0).
|
||||||
|
///
|
||||||
|
void (CEF_CALLBACK *stop)(struct _cef_thread_t* self);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns true (1) if the thread is currently running. This function must be
|
||||||
|
// called from the same thread that called cef_thread_create().
|
||||||
|
///
|
||||||
|
int (CEF_CALLBACK *is_running)(struct _cef_thread_t* self);
|
||||||
|
} cef_thread_t;
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
// Create and start a new thread. This function does not block waiting for the
|
||||||
|
// thread to run initialization. |display_name| is the name that will be used to
|
||||||
|
// identify the thread. |priority| is the thread execution priority.
|
||||||
|
// |message_loop_type| indicates the set of asynchronous events that the thread
|
||||||
|
// can process. If |stoppable| is true (1) the thread will stopped and joined on
|
||||||
|
// destruction or when stop() is called; otherwise, the the thread cannot be
|
||||||
|
// stopped and will be leaked on shutdown. On Windows the |com_init_mode| value
|
||||||
|
// specifies how COM will be initialized for the thread. If |com_init_mode| is
|
||||||
|
// set to COM_INIT_MODE_STA then |message_loop_type| must be set to ML_TYPE_UI.
|
||||||
|
///
|
||||||
|
CEF_EXPORT cef_thread_t* cef_thread_create(const cef_string_t* display_name,
|
||||||
|
cef_thread_priority_t priority, cef_message_loop_type_t message_loop_type,
|
||||||
|
int stoppable, cef_com_init_mode_t com_init_mode);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // CEF_INCLUDE_CAPI_CEF_THREAD_CAPI_H_
|
117
include/cef_thread.h
Normal file
117
include/cef_thread.h
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// Copyright (c) 2016 Marshall A. Greenblatt. All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the name Chromium Embedded
|
||||||
|
// Framework nor the names of its contributors may be used to endorse
|
||||||
|
// or promote products derived from this software without specific prior
|
||||||
|
// written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// The contents of this file must follow a specific format in order to
|
||||||
|
// support the CEF translator tool. See the translator.README.txt file in the
|
||||||
|
// tools directory for more information.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CEF_INCLUDE_CEF_THREAD_H_
|
||||||
|
#define CEF_INCLUDE_CEF_THREAD_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/cef_task.h"
|
||||||
|
#include "include/internal/cef_thread_internal.h"
|
||||||
|
|
||||||
|
///
|
||||||
|
// A simple thread abstraction that establishes a message loop on a new thread.
|
||||||
|
// The consumer uses CefTaskRunner to execute code on the thread's message loop.
|
||||||
|
// The thread is terminated when the CefThread object is destroyed or Stop() is
|
||||||
|
// called. All pending tasks queued on the thread's message loop will run to
|
||||||
|
// completion before the thread is terminated. CreateThread() can be called on
|
||||||
|
// any valid CEF thread in either the browser or render process. This class
|
||||||
|
// should only be used for tasks that require a dedicated thread. In most cases
|
||||||
|
// you can post tasks to an existing CEF thread instead of creating a new one;
|
||||||
|
// see cef_task.h for details.
|
||||||
|
///
|
||||||
|
/*--cef(source=library)--*/
|
||||||
|
class CefThread : public CefBase {
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
// Create and start a new thread. This method does not block waiting for the
|
||||||
|
// thread to run initialization. |display_name| is the name that will be used
|
||||||
|
// to identify the thread. |priority| is the thread execution priority.
|
||||||
|
// |message_loop_type| indicates the set of asynchronous events that the
|
||||||
|
// thread can process. If |stoppable| is true the thread will stopped and
|
||||||
|
// joined on destruction or when Stop() is called; otherwise, the the thread
|
||||||
|
// cannot be stopped and will be leaked on shutdown. On Windows the
|
||||||
|
// |com_init_mode| value specifies how COM will be initialized for the thread.
|
||||||
|
// If |com_init_mode| is set to COM_INIT_MODE_STA then |message_loop_type|
|
||||||
|
// must be set to ML_TYPE_UI.
|
||||||
|
///
|
||||||
|
/*--cef(optional_param=display_name)--*/
|
||||||
|
static CefRefPtr<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);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Create and start a new thread with default/recommended values.
|
||||||
|
// |display_name| is the name that will be used to identify the thread.
|
||||||
|
///
|
||||||
|
static CefRefPtr<CefThread> CreateThread(const CefString& display_name) {
|
||||||
|
return CreateThread(display_name, TP_NORMAL, ML_TYPE_DEFAULT, true,
|
||||||
|
COM_INIT_MODE_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns the CefTaskRunner that will execute code on this thread's message
|
||||||
|
// loop. This method is safe to call from any thread.
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual CefRefPtr<CefTaskRunner> GetTaskRunner() =0;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns the platform thread ID. It will return the same value after Stop()
|
||||||
|
// is called. This method is safe to call from any thread.
|
||||||
|
///
|
||||||
|
/*--cef(default_retval=kInvalidPlatformThreadId)--*/
|
||||||
|
virtual cef_platform_thread_id_t GetPlatformThreadId() =0;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Stop and join the thread. This method must be called from the same thread
|
||||||
|
// that called CreateThread(). Do not call this method if CreateThread() was
|
||||||
|
// called with a |stoppable| value of false.
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual void Stop() =0;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Returns true if the thread is currently running. This method must be called
|
||||||
|
// from the same thread that called CreateThread().
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual bool IsRunning() =0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CEF_INCLUDE_CEF_THREAD_H_
|
@ -46,8 +46,10 @@ extern "C" {
|
|||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
typedef DWORD cef_platform_thread_id_t;
|
typedef DWORD cef_platform_thread_id_t;
|
||||||
|
#define kInvalidPlatformThreadId 0U
|
||||||
#elif defined(OS_POSIX)
|
#elif defined(OS_POSIX)
|
||||||
typedef pid_t cef_platform_thread_id_t;
|
typedef pid_t cef_platform_thread_id_t;
|
||||||
|
#define kInvalidPlatformThreadId 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -57,8 +59,10 @@ CEF_EXPORT cef_platform_thread_id_t cef_get_current_platform_thread_id();
|
|||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
typedef DWORD cef_platform_thread_handle_t;
|
typedef DWORD cef_platform_thread_handle_t;
|
||||||
|
#define kInvalidPlatformThreadHandle 0U
|
||||||
#elif defined(OS_POSIX)
|
#elif defined(OS_POSIX)
|
||||||
typedef pthread_t cef_platform_thread_handle_t;
|
typedef pthread_t cef_platform_thread_handle_t;
|
||||||
|
#define kInvalidPlatformThreadHandle 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -1396,6 +1396,73 @@ typedef enum {
|
|||||||
TID_RENDERER,
|
TID_RENDERER,
|
||||||
} cef_thread_id_t;
|
} cef_thread_id_t;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Thread priority values listed in increasing order of importance.
|
||||||
|
///
|
||||||
|
typedef enum {
|
||||||
|
///
|
||||||
|
// Suitable for threads that shouldn't disrupt high priority work.
|
||||||
|
///
|
||||||
|
TP_BACKGROUND,
|
||||||
|
|
||||||
|
///
|
||||||
|
// Default priority level.
|
||||||
|
///
|
||||||
|
TP_NORMAL,
|
||||||
|
|
||||||
|
///
|
||||||
|
// Suitable for threads which generate data for the display (at ~60Hz).
|
||||||
|
///
|
||||||
|
TP_DISPLAY,
|
||||||
|
|
||||||
|
///
|
||||||
|
// Suitable for low-latency, glitch-resistant audio.
|
||||||
|
///
|
||||||
|
TP_REALTIME_AUDIO,
|
||||||
|
} cef_thread_priority_t;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Message loop types. Indicates the set of asynchronous events that a message
|
||||||
|
// loop can process.
|
||||||
|
///
|
||||||
|
typedef enum {
|
||||||
|
///
|
||||||
|
// Supports tasks and timers.
|
||||||
|
///
|
||||||
|
ML_TYPE_DEFAULT,
|
||||||
|
|
||||||
|
///
|
||||||
|
// Supports tasks, timers and native UI events (e.g. Windows messages).
|
||||||
|
///
|
||||||
|
ML_TYPE_UI,
|
||||||
|
|
||||||
|
///
|
||||||
|
// Supports tasks, timers and asynchronous IO events.
|
||||||
|
///
|
||||||
|
ML_TYPE_IO,
|
||||||
|
} cef_message_loop_type_t;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Windows COM initialization mode. Specifies how COM will be initialized for a
|
||||||
|
// new thread.
|
||||||
|
///
|
||||||
|
typedef enum {
|
||||||
|
///
|
||||||
|
// No COM initialization.
|
||||||
|
///
|
||||||
|
COM_INIT_MODE_NONE,
|
||||||
|
|
||||||
|
///
|
||||||
|
// Initialize COM using single-threaded apartments.
|
||||||
|
///
|
||||||
|
COM_INIT_MODE_STA,
|
||||||
|
|
||||||
|
///
|
||||||
|
// Initialize COM using multi-threaded apartments.
|
||||||
|
///
|
||||||
|
COM_INIT_MODE_MTA,
|
||||||
|
} cef_com_init_mode_t;
|
||||||
|
|
||||||
///
|
///
|
||||||
// Supported value types.
|
// Supported value types.
|
||||||
///
|
///
|
||||||
|
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();
|
||||||
|
}
|
41
libcef/common/thread_impl.h
Normal file
41
libcef/common/thread_impl.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#ifndef CEF_LIBCEF_COMMON_THREAD_IMPL_H_
|
||||||
|
#define CEF_LIBCEF_COMMON_THREAD_IMPL_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/cef_thread.h"
|
||||||
|
#include "base/threading/thread.h"
|
||||||
|
|
||||||
|
class CefThreadImpl : public CefThread {
|
||||||
|
public:
|
||||||
|
CefThreadImpl();
|
||||||
|
~CefThreadImpl();
|
||||||
|
|
||||||
|
bool 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);
|
||||||
|
|
||||||
|
// CefThread methods:
|
||||||
|
CefRefPtr<CefTaskRunner> GetTaskRunner() override;
|
||||||
|
cef_platform_thread_id_t GetPlatformThreadId() override;
|
||||||
|
void Stop() override;
|
||||||
|
bool IsRunning() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<base::Thread> thread_;
|
||||||
|
cef_platform_thread_id_t thread_id_;
|
||||||
|
CefRefPtr<CefTaskRunner> thread_task_runner_;
|
||||||
|
|
||||||
|
// TaskRunner for the owner thread.
|
||||||
|
scoped_refptr<base::SequencedTaskRunner> owner_task_runner_;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(CefThreadImpl);
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(CefThreadImpl);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CEF_LIBCEF_COMMON_THREAD_IMPL_H_
|
124
libcef_dll/cpptoc/thread_cpptoc.cc
Normal file
124
libcef_dll/cpptoc/thread_cpptoc.cc
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
// Copyright (c) 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.
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file was generated by the CEF translator tool. If making changes by
|
||||||
|
// hand only do so within the body of existing method and function
|
||||||
|
// implementations. See the translator.README.txt file in the tools directory
|
||||||
|
// for more information.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "libcef_dll/cpptoc/task_runner_cpptoc.h"
|
||||||
|
#include "libcef_dll/cpptoc/thread_cpptoc.h"
|
||||||
|
|
||||||
|
|
||||||
|
// GLOBAL FUNCTIONS - Body may be edited by hand.
|
||||||
|
|
||||||
|
CEF_EXPORT cef_thread_t* cef_thread_create(const cef_string_t* display_name,
|
||||||
|
cef_thread_priority_t priority, cef_message_loop_type_t message_loop_type,
|
||||||
|
int stoppable, cef_com_init_mode_t com_init_mode) {
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
// Unverified params: display_name
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
CefRefPtr<CefThread> _retval = CefThread::CreateThread(
|
||||||
|
CefString(display_name),
|
||||||
|
priority,
|
||||||
|
message_loop_type,
|
||||||
|
stoppable?true:false,
|
||||||
|
com_init_mode);
|
||||||
|
|
||||||
|
// Return type: refptr_same
|
||||||
|
return CefThreadCppToC::Wrap(_retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// MEMBER FUNCTIONS - Body may be edited by hand.
|
||||||
|
|
||||||
|
cef_task_runner_t* CEF_CALLBACK thread_get_task_runner(
|
||||||
|
struct _cef_thread_t* self) {
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
DCHECK(self);
|
||||||
|
if (!self)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
CefRefPtr<CefTaskRunner> _retval = CefThreadCppToC::Get(self)->GetTaskRunner(
|
||||||
|
);
|
||||||
|
|
||||||
|
// Return type: refptr_same
|
||||||
|
return CefTaskRunnerCppToC::Wrap(_retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
cef_platform_thread_id_t CEF_CALLBACK thread_get_platform_thread_id(
|
||||||
|
struct _cef_thread_t* self) {
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
DCHECK(self);
|
||||||
|
if (!self)
|
||||||
|
return kInvalidPlatformThreadId;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
cef_platform_thread_id_t _retval = CefThreadCppToC::Get(
|
||||||
|
self)->GetPlatformThreadId();
|
||||||
|
|
||||||
|
// Return type: simple
|
||||||
|
return _retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEF_CALLBACK thread_stop(struct _cef_thread_t* self) {
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
DCHECK(self);
|
||||||
|
if (!self)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
CefThreadCppToC::Get(self)->Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
int CEF_CALLBACK thread_is_running(struct _cef_thread_t* self) {
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
DCHECK(self);
|
||||||
|
if (!self)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
bool _retval = CefThreadCppToC::Get(self)->IsRunning();
|
||||||
|
|
||||||
|
// Return type: bool
|
||||||
|
return _retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
// CONSTRUCTOR - Do not edit by hand.
|
||||||
|
|
||||||
|
CefThreadCppToC::CefThreadCppToC() {
|
||||||
|
GetStruct()->get_task_runner = thread_get_task_runner;
|
||||||
|
GetStruct()->get_platform_thread_id = thread_get_platform_thread_id;
|
||||||
|
GetStruct()->stop = thread_stop;
|
||||||
|
GetStruct()->is_running = thread_is_running;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> CefRefPtr<CefThread> CefCppToC<CefThreadCppToC, CefThread,
|
||||||
|
cef_thread_t>::UnwrapDerived(CefWrapperType type, cef_thread_t* s) {
|
||||||
|
NOTREACHED() << "Unexpected class type: " << type;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DCHECK_IS_ON()
|
||||||
|
template<> base::AtomicRefCount CefCppToC<CefThreadCppToC, CefThread,
|
||||||
|
cef_thread_t>::DebugObjCt = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<> CefWrapperType CefCppToC<CefThreadCppToC, CefThread,
|
||||||
|
cef_thread_t>::kWrapperType = WT_THREAD;
|
34
libcef_dll/cpptoc/thread_cpptoc.h
Normal file
34
libcef_dll/cpptoc/thread_cpptoc.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Copyright (c) 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.
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file was generated by the CEF translator tool. If making changes by
|
||||||
|
// hand only do so within the body of existing method and function
|
||||||
|
// implementations. See the translator.README.txt file in the tools directory
|
||||||
|
// for more information.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CEF_LIBCEF_DLL_CPPTOC_THREAD_CPPTOC_H_
|
||||||
|
#define CEF_LIBCEF_DLL_CPPTOC_THREAD_CPPTOC_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef BUILDING_CEF_SHARED
|
||||||
|
#pragma message("Warning: "__FILE__" may be accessed DLL-side only")
|
||||||
|
#else // BUILDING_CEF_SHARED
|
||||||
|
|
||||||
|
#include "include/cef_thread.h"
|
||||||
|
#include "include/capi/cef_thread_capi.h"
|
||||||
|
#include "libcef_dll/cpptoc/cpptoc.h"
|
||||||
|
|
||||||
|
// Wrap a C++ class with a C structure.
|
||||||
|
// This class may be instantiated and accessed DLL-side only.
|
||||||
|
class CefThreadCppToC
|
||||||
|
: public CefCppToC<CefThreadCppToC, CefThread, cef_thread_t> {
|
||||||
|
public:
|
||||||
|
CefThreadCppToC();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BUILDING_CEF_SHARED
|
||||||
|
#endif // CEF_LIBCEF_DLL_CPPTOC_THREAD_CPPTOC_H_
|
112
libcef_dll/ctocpp/thread_ctocpp.cc
Normal file
112
libcef_dll/ctocpp/thread_ctocpp.cc
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
// Copyright (c) 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.
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file was generated by the CEF translator tool. If making changes by
|
||||||
|
// hand only do so within the body of existing method and function
|
||||||
|
// implementations. See the translator.README.txt file in the tools directory
|
||||||
|
// for more information.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "libcef_dll/ctocpp/task_runner_ctocpp.h"
|
||||||
|
#include "libcef_dll/ctocpp/thread_ctocpp.h"
|
||||||
|
|
||||||
|
|
||||||
|
// STATIC METHODS - Body may be edited by hand.
|
||||||
|
|
||||||
|
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) {
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
// Unverified params: display_name
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
cef_thread_t* _retval = cef_thread_create(
|
||||||
|
display_name.GetStruct(),
|
||||||
|
priority,
|
||||||
|
message_loop_type,
|
||||||
|
stoppable,
|
||||||
|
com_init_mode);
|
||||||
|
|
||||||
|
// Return type: refptr_same
|
||||||
|
return CefThreadCToCpp::Wrap(_retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// VIRTUAL METHODS - Body may be edited by hand.
|
||||||
|
|
||||||
|
CefRefPtr<CefTaskRunner> CefThreadCToCpp::GetTaskRunner() {
|
||||||
|
cef_thread_t* _struct = GetStruct();
|
||||||
|
if (CEF_MEMBER_MISSING(_struct, get_task_runner))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
cef_task_runner_t* _retval = _struct->get_task_runner(_struct);
|
||||||
|
|
||||||
|
// Return type: refptr_same
|
||||||
|
return CefTaskRunnerCToCpp::Wrap(_retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
cef_platform_thread_id_t CefThreadCToCpp::GetPlatformThreadId() {
|
||||||
|
cef_thread_t* _struct = GetStruct();
|
||||||
|
if (CEF_MEMBER_MISSING(_struct, get_platform_thread_id))
|
||||||
|
return kInvalidPlatformThreadId;
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
cef_platform_thread_id_t _retval = _struct->get_platform_thread_id(_struct);
|
||||||
|
|
||||||
|
// Return type: simple
|
||||||
|
return _retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CefThreadCToCpp::Stop() {
|
||||||
|
cef_thread_t* _struct = GetStruct();
|
||||||
|
if (CEF_MEMBER_MISSING(_struct, stop))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
_struct->stop(_struct);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CefThreadCToCpp::IsRunning() {
|
||||||
|
cef_thread_t* _struct = GetStruct();
|
||||||
|
if (CEF_MEMBER_MISSING(_struct, is_running))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
int _retval = _struct->is_running(_struct);
|
||||||
|
|
||||||
|
// Return type: bool
|
||||||
|
return _retval?true:false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// CONSTRUCTOR - Do not edit by hand.
|
||||||
|
|
||||||
|
CefThreadCToCpp::CefThreadCToCpp() {
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> cef_thread_t* CefCToCpp<CefThreadCToCpp, CefThread,
|
||||||
|
cef_thread_t>::UnwrapDerived(CefWrapperType type, CefThread* c) {
|
||||||
|
NOTREACHED() << "Unexpected class type: " << type;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DCHECK_IS_ON()
|
||||||
|
template<> base::AtomicRefCount CefCToCpp<CefThreadCToCpp, CefThread,
|
||||||
|
cef_thread_t>::DebugObjCt = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<> CefWrapperType CefCToCpp<CefThreadCToCpp, CefThread,
|
||||||
|
cef_thread_t>::kWrapperType = WT_THREAD;
|
40
libcef_dll/ctocpp/thread_ctocpp.h
Normal file
40
libcef_dll/ctocpp/thread_ctocpp.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// Copyright (c) 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.
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file was generated by the CEF translator tool. If making changes by
|
||||||
|
// hand only do so within the body of existing method and function
|
||||||
|
// implementations. See the translator.README.txt file in the tools directory
|
||||||
|
// for more information.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CEF_LIBCEF_DLL_CTOCPP_THREAD_CTOCPP_H_
|
||||||
|
#define CEF_LIBCEF_DLL_CTOCPP_THREAD_CTOCPP_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef USING_CEF_SHARED
|
||||||
|
#pragma message("Warning: "__FILE__" may be accessed wrapper-side only")
|
||||||
|
#else // USING_CEF_SHARED
|
||||||
|
|
||||||
|
#include "include/cef_thread.h"
|
||||||
|
#include "include/capi/cef_thread_capi.h"
|
||||||
|
#include "libcef_dll/ctocpp/ctocpp.h"
|
||||||
|
|
||||||
|
// Wrap a C structure with a C++ class.
|
||||||
|
// This class may be instantiated and accessed wrapper-side only.
|
||||||
|
class CefThreadCToCpp
|
||||||
|
: public CefCToCpp<CefThreadCToCpp, CefThread, cef_thread_t> {
|
||||||
|
public:
|
||||||
|
CefThreadCToCpp();
|
||||||
|
|
||||||
|
// CefThread methods.
|
||||||
|
CefRefPtr<CefTaskRunner> GetTaskRunner() OVERRIDE;
|
||||||
|
cef_platform_thread_id_t GetPlatformThreadId() OVERRIDE;
|
||||||
|
void Stop() OVERRIDE;
|
||||||
|
bool IsRunning() OVERRIDE;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // USING_CEF_SHARED
|
||||||
|
#endif // CEF_LIBCEF_DLL_CTOCPP_THREAD_CTOCPP_H_
|
@ -80,6 +80,7 @@
|
|||||||
#include "libcef_dll/cpptoc/stream_writer_cpptoc.h"
|
#include "libcef_dll/cpptoc/stream_writer_cpptoc.h"
|
||||||
#include "libcef_dll/cpptoc/task_runner_cpptoc.h"
|
#include "libcef_dll/cpptoc/task_runner_cpptoc.h"
|
||||||
#include "libcef_dll/cpptoc/views/textfield_cpptoc.h"
|
#include "libcef_dll/cpptoc/views/textfield_cpptoc.h"
|
||||||
|
#include "libcef_dll/cpptoc/thread_cpptoc.h"
|
||||||
#include "libcef_dll/cpptoc/urlrequest_cpptoc.h"
|
#include "libcef_dll/cpptoc/urlrequest_cpptoc.h"
|
||||||
#include "libcef_dll/cpptoc/v8context_cpptoc.h"
|
#include "libcef_dll/cpptoc/v8context_cpptoc.h"
|
||||||
#include "libcef_dll/cpptoc/v8exception_cpptoc.h"
|
#include "libcef_dll/cpptoc/v8exception_cpptoc.h"
|
||||||
@ -321,6 +322,7 @@ CEF_EXPORT void cef_shutdown() {
|
|||||||
DCHECK(base::AtomicRefCountIsZero(&CefTaskRunnerCppToC::DebugObjCt));
|
DCHECK(base::AtomicRefCountIsZero(&CefTaskRunnerCppToC::DebugObjCt));
|
||||||
DCHECK(base::AtomicRefCountIsZero(&CefTextfieldCppToC::DebugObjCt));
|
DCHECK(base::AtomicRefCountIsZero(&CefTextfieldCppToC::DebugObjCt));
|
||||||
DCHECK(base::AtomicRefCountIsZero(&CefTextfieldDelegateCToCpp::DebugObjCt));
|
DCHECK(base::AtomicRefCountIsZero(&CefTextfieldDelegateCToCpp::DebugObjCt));
|
||||||
|
DCHECK(base::AtomicRefCountIsZero(&CefThreadCppToC::DebugObjCt));
|
||||||
DCHECK(base::AtomicRefCountIsZero(&CefURLRequestClientCToCpp::DebugObjCt));
|
DCHECK(base::AtomicRefCountIsZero(&CefURLRequestClientCToCpp::DebugObjCt));
|
||||||
DCHECK(base::AtomicRefCountIsZero(&CefURLRequestCppToC::DebugObjCt));
|
DCHECK(base::AtomicRefCountIsZero(&CefURLRequestCppToC::DebugObjCt));
|
||||||
DCHECK(base::AtomicRefCountIsZero(&CefV8AccessorCToCpp::DebugObjCt));
|
DCHECK(base::AtomicRefCountIsZero(&CefV8AccessorCToCpp::DebugObjCt));
|
||||||
|
@ -134,6 +134,7 @@
|
|||||||
#include "libcef_dll/ctocpp/stream_writer_ctocpp.h"
|
#include "libcef_dll/ctocpp/stream_writer_ctocpp.h"
|
||||||
#include "libcef_dll/ctocpp/task_runner_ctocpp.h"
|
#include "libcef_dll/ctocpp/task_runner_ctocpp.h"
|
||||||
#include "libcef_dll/ctocpp/views/textfield_ctocpp.h"
|
#include "libcef_dll/ctocpp/views/textfield_ctocpp.h"
|
||||||
|
#include "libcef_dll/ctocpp/thread_ctocpp.h"
|
||||||
#include "libcef_dll/ctocpp/urlrequest_ctocpp.h"
|
#include "libcef_dll/ctocpp/urlrequest_ctocpp.h"
|
||||||
#include "libcef_dll/ctocpp/v8context_ctocpp.h"
|
#include "libcef_dll/ctocpp/v8context_ctocpp.h"
|
||||||
#include "libcef_dll/ctocpp/v8exception_ctocpp.h"
|
#include "libcef_dll/ctocpp/v8exception_ctocpp.h"
|
||||||
@ -313,6 +314,7 @@ CEF_GLOBAL void CefShutdown() {
|
|||||||
DCHECK(base::AtomicRefCountIsZero(&CefTaskRunnerCToCpp::DebugObjCt));
|
DCHECK(base::AtomicRefCountIsZero(&CefTaskRunnerCToCpp::DebugObjCt));
|
||||||
DCHECK(base::AtomicRefCountIsZero(&CefTextfieldCToCpp::DebugObjCt));
|
DCHECK(base::AtomicRefCountIsZero(&CefTextfieldCToCpp::DebugObjCt));
|
||||||
DCHECK(base::AtomicRefCountIsZero(&CefTextfieldDelegateCppToC::DebugObjCt));
|
DCHECK(base::AtomicRefCountIsZero(&CefTextfieldDelegateCppToC::DebugObjCt));
|
||||||
|
DCHECK(base::AtomicRefCountIsZero(&CefThreadCToCpp::DebugObjCt));
|
||||||
DCHECK(base::AtomicRefCountIsZero(&CefURLRequestCToCpp::DebugObjCt));
|
DCHECK(base::AtomicRefCountIsZero(&CefURLRequestCToCpp::DebugObjCt));
|
||||||
DCHECK(base::AtomicRefCountIsZero(&CefURLRequestClientCppToC::DebugObjCt));
|
DCHECK(base::AtomicRefCountIsZero(&CefURLRequestClientCppToC::DebugObjCt));
|
||||||
DCHECK(base::AtomicRefCountIsZero(&CefV8AccessorCppToC::DebugObjCt));
|
DCHECK(base::AtomicRefCountIsZero(&CefV8AccessorCppToC::DebugObjCt));
|
||||||
|
@ -115,6 +115,7 @@ enum CefWrapperType {
|
|||||||
WT_TASK_RUNNER,
|
WT_TASK_RUNNER,
|
||||||
WT_TEXTFIELD,
|
WT_TEXTFIELD,
|
||||||
WT_TEXTFIELD_DELEGATE,
|
WT_TEXTFIELD_DELEGATE,
|
||||||
|
WT_THREAD,
|
||||||
WT_TRANSLATOR_TEST,
|
WT_TRANSLATOR_TEST,
|
||||||
WT_TRANSLATOR_TEST_HANDLER,
|
WT_TRANSLATOR_TEST_HANDLER,
|
||||||
WT_TRANSLATOR_TEST_HANDLER_CHILD,
|
WT_TRANSLATOR_TEST_HANDLER_CHILD,
|
||||||
|
@ -81,6 +81,11 @@ void CreateRenderDelegates(ClientAppRenderer::DelegateSet& delegates) {
|
|||||||
ClientAppRenderer::DelegateSet& delegates);
|
ClientAppRenderer::DelegateSet& delegates);
|
||||||
CreateRoutingTestHandlerDelegate(delegates);
|
CreateRoutingTestHandlerDelegate(delegates);
|
||||||
|
|
||||||
|
// Bring in the thread tests.
|
||||||
|
extern void CreateThreadRendererTests(
|
||||||
|
ClientAppRenderer::DelegateSet& delegates);
|
||||||
|
CreateThreadRendererTests(delegates);
|
||||||
|
|
||||||
// Bring in the URLRequest tests.
|
// Bring in the URLRequest tests.
|
||||||
extern void CreateURLRequestRendererTests(
|
extern void CreateURLRequestRendererTests(
|
||||||
ClientAppRenderer::DelegateSet& delegates);
|
ClientAppRenderer::DelegateSet& delegates);
|
||||||
|
@ -11,11 +11,10 @@
|
|||||||
#undef Bool
|
#undef Bool
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "base/threading/thread.h"
|
|
||||||
|
|
||||||
#include "include/base/cef_bind.h"
|
#include "include/base/cef_bind.h"
|
||||||
#include "include/cef_app.h"
|
#include "include/cef_app.h"
|
||||||
#include "include/cef_task.h"
|
#include "include/cef_task.h"
|
||||||
|
#include "include/cef_thread.h"
|
||||||
#include "include/wrapper/cef_helpers.h"
|
#include "include/wrapper/cef_helpers.h"
|
||||||
#include "include/wrapper/cef_closure_task.h"
|
#include "include/wrapper/cef_closure_task.h"
|
||||||
#include "tests/cefclient/browser/client_app_browser.h"
|
#include "tests/cefclient/browser/client_app_browser.h"
|
||||||
@ -32,6 +31,12 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
// Used to track state when running tests on a separate thread.
|
||||||
|
struct TestState {
|
||||||
|
CefTestSuite* test_suite_;
|
||||||
|
int retval_;
|
||||||
|
};
|
||||||
|
|
||||||
void QuitMessageLoop() {
|
void QuitMessageLoop() {
|
||||||
client::MainMessageLoop* message_loop = client::MainMessageLoop::Get();
|
client::MainMessageLoop* message_loop = client::MainMessageLoop::Get();
|
||||||
if (message_loop)
|
if (message_loop)
|
||||||
@ -40,38 +45,28 @@ void QuitMessageLoop() {
|
|||||||
CefQuitMessageLoop();
|
CefQuitMessageLoop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Thread used to run the test suite.
|
// Called on the test thread.
|
||||||
class CefTestThread : public base::Thread {
|
void RunTestsOnTestThread(TestState* test_state) {
|
||||||
public:
|
CHECK(test_state);
|
||||||
explicit CefTestThread(CefTestSuite* test_suite)
|
|
||||||
: base::Thread("test_thread"),
|
|
||||||
test_suite_(test_suite) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunTests() {
|
// Run the test suite.
|
||||||
// Run the test suite.
|
test_state->retval_ = test_state->test_suite_->Run();
|
||||||
retval_ = test_suite_->Run();
|
|
||||||
|
|
||||||
// Wait for all browsers to exit.
|
// Wait for all browsers to exit.
|
||||||
while (TestHandler::HasBrowser())
|
while (TestHandler::HasBrowser())
|
||||||
base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
|
base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
|
||||||
|
|
||||||
// Quit the CEF message loop.
|
// Quit the CEF message loop.
|
||||||
CefPostTask(TID_UI, base::Bind(&QuitMessageLoop));
|
CefPostTask(TID_UI, base::Bind(&QuitMessageLoop));
|
||||||
}
|
}
|
||||||
|
|
||||||
int retval() { return retval_; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
CefTestSuite* test_suite_;
|
|
||||||
int retval_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Called on the UI thread.
|
// Called on the UI thread.
|
||||||
void RunTests(CefTestThread* thread) {
|
void ContinueOnUIThread(TestState* test_state,
|
||||||
|
CefRefPtr<CefTaskRunner> test_task_runner) {
|
||||||
// Run the test suite on the test thread.
|
// Run the test suite on the test thread.
|
||||||
thread->message_loop()->task_runner()->PostTask(FROM_HERE,
|
test_task_runner->PostTask(
|
||||||
base::Bind(&CefTestThread::RunTests, base::Unretained(thread)));
|
CefCreateClosureTask(base::Bind(&RunTestsOnTestThread,
|
||||||
|
base::Unretained(test_state))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(OS_LINUX)
|
#if defined(OS_LINUX)
|
||||||
@ -189,24 +184,29 @@ int main(int argc, char* argv[]) {
|
|||||||
// Run the test suite on the main thread.
|
// Run the test suite on the main thread.
|
||||||
retval = test_suite.Run();
|
retval = test_suite.Run();
|
||||||
} else {
|
} else {
|
||||||
// Create the test thread.
|
TestState test_state = {0};
|
||||||
std::unique_ptr<CefTestThread> thread;
|
test_state.test_suite_ = &test_suite;
|
||||||
thread.reset(new CefTestThread(&test_suite));
|
|
||||||
if (!thread->Start())
|
// Create and start the test thread.
|
||||||
|
CefRefPtr<CefThread> thread = CefThread::CreateThread("test_thread");
|
||||||
|
if (!thread)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// Start the tests from the UI thread so that any pending UI tasks get a
|
// Start the tests from the UI thread so that any pending UI tasks get a
|
||||||
// chance to execute first.
|
// chance to execute first.
|
||||||
CefPostTask(TID_UI, base::Bind(&RunTests, thread.get()));
|
CefPostTask(TID_UI,
|
||||||
|
base::Bind(&ContinueOnUIThread, base::Unretained(&test_state),
|
||||||
|
thread->GetTaskRunner()));
|
||||||
|
|
||||||
// Run the CEF message loop.
|
// Run the CEF message loop.
|
||||||
message_loop->Run();
|
message_loop->Run();
|
||||||
|
|
||||||
// The test suite has completed.
|
// The test suite has completed.
|
||||||
retval = thread->retval();
|
retval = test_state.retval_;
|
||||||
|
|
||||||
// Terminate the test thread.
|
// Terminate the test thread.
|
||||||
thread.reset();
|
thread->Stop();
|
||||||
|
thread = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shut down CEF.
|
// Shut down CEF.
|
||||||
|
440
tests/unittests/thread_unittest.cc
Normal file
440
tests/unittests/thread_unittest.cc
Normal file
@ -0,0 +1,440 @@
|
|||||||
|
// 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 "include/base/cef_bind.h"
|
||||||
|
#include "include/cef_task.h"
|
||||||
|
#include "include/cef_thread.h"
|
||||||
|
#include "include/wrapper/cef_closure_task.h"
|
||||||
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
#include "tests/cefclient/browser/client_app_browser.h"
|
||||||
|
#include "tests/cefclient/renderer/client_app_renderer.h"
|
||||||
|
#include "tests/unittests/test_handler.h"
|
||||||
|
|
||||||
|
using client::ClientAppBrowser;
|
||||||
|
using client::ClientAppRenderer;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Base class for creating and testing threads.
|
||||||
|
class ThreadTest : public base::RefCountedThreadSafe<ThreadTest> {
|
||||||
|
public:
|
||||||
|
ThreadTest() {}
|
||||||
|
virtual ~ThreadTest() {}
|
||||||
|
|
||||||
|
// Create the test thread. Should only be called one time.
|
||||||
|
void CreateTestThread() {
|
||||||
|
EXPECT_TRUE(!thread_.get());
|
||||||
|
|
||||||
|
owner_task_runner_ = CefTaskRunner::GetForCurrentThread();
|
||||||
|
EXPECT_TRUE(owner_task_runner_.get());
|
||||||
|
EXPECT_TRUE(owner_task_runner_->BelongsToCurrentThread());
|
||||||
|
|
||||||
|
thread_ = CefThread::CreateThread("test_thread");
|
||||||
|
EXPECT_TRUE(thread_.get());
|
||||||
|
EXPECT_TRUE(thread_->IsRunning());
|
||||||
|
|
||||||
|
thread_id_ = thread_->GetPlatformThreadId();
|
||||||
|
EXPECT_NE(thread_id_, kInvalidPlatformThreadId);
|
||||||
|
|
||||||
|
thread_task_runner_ = thread_->GetTaskRunner();
|
||||||
|
EXPECT_TRUE(thread_task_runner_.get());
|
||||||
|
|
||||||
|
AssertOwnerThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destroy the test thread. Should only be called one time.
|
||||||
|
void DestroyTestThread() {
|
||||||
|
EXPECT_TRUE(thread_.get());
|
||||||
|
AssertOwnerThread();
|
||||||
|
|
||||||
|
EXPECT_TRUE(thread_->IsRunning());
|
||||||
|
thread_->Stop();
|
||||||
|
EXPECT_FALSE(thread_->IsRunning());
|
||||||
|
|
||||||
|
AssertOwnerThread();
|
||||||
|
|
||||||
|
thread_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute |test_task| on the test thread. After execution |callback| will be
|
||||||
|
// posted to |callback_task_runner|.
|
||||||
|
void PostOnTestThreadAndCallback(
|
||||||
|
const base::Closure& test_task,
|
||||||
|
CefRefPtr<CefTaskRunner> callback_task_runner,
|
||||||
|
const base::Closure& callback) {
|
||||||
|
EXPECT_TRUE(thread_.get());
|
||||||
|
thread_task_runner_->PostTask(CefCreateClosureTask(
|
||||||
|
base::Bind(&ThreadTest::ExecuteOnTestThread, this, test_task,
|
||||||
|
callback_task_runner, callback)));
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefTaskRunner> owner_task_runner() const {
|
||||||
|
return owner_task_runner_;
|
||||||
|
}
|
||||||
|
CefRefPtr<CefTaskRunner> thread_task_runner() const {
|
||||||
|
return thread_task_runner_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert that we're running on the owner thread.
|
||||||
|
void AssertOwnerThread() {
|
||||||
|
EXPECT_TRUE(owner_task_runner_->BelongsToCurrentThread());
|
||||||
|
EXPECT_FALSE(thread_task_runner_->BelongsToCurrentThread());
|
||||||
|
EXPECT_TRUE(thread_task_runner_->IsSame(thread_->GetTaskRunner()));
|
||||||
|
EXPECT_EQ(thread_id_, thread_->GetPlatformThreadId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert that we're running on the test thread.
|
||||||
|
void AssertTestThread() {
|
||||||
|
EXPECT_FALSE(owner_task_runner_->BelongsToCurrentThread());
|
||||||
|
EXPECT_TRUE(thread_task_runner_->BelongsToCurrentThread());
|
||||||
|
EXPECT_TRUE(thread_task_runner_->IsSame(thread_->GetTaskRunner()));
|
||||||
|
EXPECT_EQ(thread_id_, thread_->GetPlatformThreadId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Helper for PostOnTestThreadAndCallback().
|
||||||
|
void ExecuteOnTestThread(const base::Closure& test_task,
|
||||||
|
CefRefPtr<CefTaskRunner> callback_task_runner,
|
||||||
|
const base::Closure& callback) {
|
||||||
|
AssertTestThread();
|
||||||
|
|
||||||
|
test_task.Run();
|
||||||
|
|
||||||
|
callback_task_runner->PostTask(CefCreateClosureTask(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefTaskRunner> owner_task_runner_;
|
||||||
|
|
||||||
|
CefRefPtr<CefThread> thread_;
|
||||||
|
cef_platform_thread_id_t thread_id_;
|
||||||
|
CefRefPtr<CefTaskRunner> thread_task_runner_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ThreadTest);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Test thread creation and destruction without any task execution.
|
||||||
|
TEST(ThreadTest, Create) {
|
||||||
|
scoped_refptr<ThreadTest> thread_test = new ThreadTest();
|
||||||
|
thread_test->CreateTestThread();
|
||||||
|
thread_test->DestroyTestThread();
|
||||||
|
thread_test = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Simple implementation of ThreadTest that creates a thread, executes tasks
|
||||||
|
// on the thread, then destroys the thread after all tasks have completed.
|
||||||
|
class SimpleThreadTest : public ThreadTest {
|
||||||
|
public:
|
||||||
|
SimpleThreadTest(size_t expected_task_count,
|
||||||
|
const base::Closure& task_callback,
|
||||||
|
const base::Closure& done_callback)
|
||||||
|
: expected_task_count_(expected_task_count),
|
||||||
|
task_callback_(task_callback),
|
||||||
|
done_callback_(done_callback),
|
||||||
|
got_task_count_(0U),
|
||||||
|
got_done_count_(0U) {}
|
||||||
|
|
||||||
|
void RunTest() {
|
||||||
|
// Create the test thread.
|
||||||
|
CreateTestThread();
|
||||||
|
|
||||||
|
for (size_t i = 0U; i < expected_task_count_; ++i) {
|
||||||
|
// Execute Task() on the test thread and then call Done() on this thread.
|
||||||
|
PostOnTestThreadAndCallback(
|
||||||
|
base::Bind(&SimpleThreadTest::Task, this), owner_task_runner(),
|
||||||
|
base::Bind(&SimpleThreadTest::Done, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyTest() {
|
||||||
|
EXPECT_EQ(expected_task_count_, got_task_count_);
|
||||||
|
EXPECT_EQ(expected_task_count_, got_done_count_);
|
||||||
|
|
||||||
|
// Destroy the test thread.
|
||||||
|
DestroyTestThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Task() {
|
||||||
|
AssertTestThread();
|
||||||
|
got_task_count_++;
|
||||||
|
if (!task_callback_.is_null())
|
||||||
|
task_callback_.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Done() {
|
||||||
|
AssertOwnerThread();
|
||||||
|
if (++got_done_count_ == expected_task_count_ && !done_callback_.is_null())
|
||||||
|
done_callback_.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t expected_task_count_;
|
||||||
|
base::Closure task_callback_;
|
||||||
|
base::Closure done_callback_;
|
||||||
|
|
||||||
|
size_t got_task_count_;
|
||||||
|
size_t got_done_count_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(SimpleThreadTest);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Test creation/execution of threads in the browser process.
|
||||||
|
|
||||||
|
const char kBrowserThreadTestHtml[] = "http://test.com/browserthread.html";
|
||||||
|
|
||||||
|
// Browser side.
|
||||||
|
class BrowserThreadTestHandler : public TestHandler {
|
||||||
|
public:
|
||||||
|
explicit BrowserThreadTestHandler(CefThreadId owner_thread_id)
|
||||||
|
: owner_thread_id_(owner_thread_id) {}
|
||||||
|
|
||||||
|
void RunTest() override {
|
||||||
|
AddResource(kBrowserThreadTestHtml, "<html><body>Test</body></html>",
|
||||||
|
"text/html");
|
||||||
|
|
||||||
|
CreateBrowser(kBrowserThreadTestHtml);
|
||||||
|
|
||||||
|
// Time out the test after a reasonable period of time.
|
||||||
|
SetTestTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunThreadTestOnOwnerThread() {
|
||||||
|
if (!CefCurrentlyOn(owner_thread_id_)) {
|
||||||
|
// Run the test on the desired owner thread.
|
||||||
|
CefPostTask(owner_thread_id_,
|
||||||
|
base::Bind(&BrowserThreadTestHandler::RunThreadTestOnOwnerThread,
|
||||||
|
this));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_FALSE(thread_test_.get());
|
||||||
|
thread_test_ = new SimpleThreadTest(
|
||||||
|
3, base::Closure(),
|
||||||
|
base::Bind(&BrowserThreadTestHandler::DoneOnOwnerThread, this));
|
||||||
|
thread_test_->RunTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoneOnOwnerThread() {
|
||||||
|
// Let the call stack unwind before destroying |thread_test_|.
|
||||||
|
CefPostTask(owner_thread_id_,
|
||||||
|
base::Bind(&BrowserThreadTestHandler::DestroyTestOnOwnerThread, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyTestOnOwnerThread() {
|
||||||
|
EXPECT_TRUE(CefCurrentlyOn(owner_thread_id_));
|
||||||
|
|
||||||
|
EXPECT_TRUE(thread_test_.get());
|
||||||
|
if (thread_test_) {
|
||||||
|
thread_test_->DestroyTest();
|
||||||
|
thread_test_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
got_test_done_.yes();
|
||||||
|
|
||||||
|
// Call DestroyTest() on the UI thread.
|
||||||
|
CefPostTask(TID_UI,
|
||||||
|
base::Bind(&BrowserThreadTestHandler::DestroyTest, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
||||||
|
bool isLoading,
|
||||||
|
bool canGoBack,
|
||||||
|
bool canGoForward) override {
|
||||||
|
if (!isLoading)
|
||||||
|
RunThreadTestOnOwnerThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DestroyTest() override {
|
||||||
|
EXPECT_FALSE(thread_test_.get());
|
||||||
|
EXPECT_TRUE(got_test_done_);
|
||||||
|
|
||||||
|
TestHandler::DestroyTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const CefThreadId owner_thread_id_;
|
||||||
|
|
||||||
|
scoped_refptr<SimpleThreadTest> thread_test_;
|
||||||
|
TrackCallback got_test_done_;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(BrowserThreadTestHandler);
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(BrowserThreadTestHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Test creation of new threads from the browser UI thread.
|
||||||
|
TEST(ThreadTest, CreateFromBrowserUIThread) {
|
||||||
|
CefRefPtr<BrowserThreadTestHandler> handler =
|
||||||
|
new BrowserThreadTestHandler(TID_UI);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test creation of new threads from the browser IO thread.
|
||||||
|
TEST(ThreadTest, CreateFromBrowserIOThread) {
|
||||||
|
CefRefPtr<BrowserThreadTestHandler> handler =
|
||||||
|
new BrowserThreadTestHandler(TID_IO);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test creation of new threads from the browser FILE thread.
|
||||||
|
TEST(ThreadTest, CreateFromBrowserFILEThread) {
|
||||||
|
CefRefPtr<BrowserThreadTestHandler> handler =
|
||||||
|
new BrowserThreadTestHandler(TID_FILE);
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Test creation/execution of threads in the render process.
|
||||||
|
|
||||||
|
const char kRenderThreadTestHtml[] = "http://test.com/renderthread.html";
|
||||||
|
const char kRenderThreadTestMsg[] = "ThreadTest.RenderThreadTest";
|
||||||
|
|
||||||
|
// Browser side.
|
||||||
|
class RenderThreadTestHandler : public TestHandler {
|
||||||
|
public:
|
||||||
|
RenderThreadTestHandler() {}
|
||||||
|
|
||||||
|
void RunTest() override {
|
||||||
|
AddResource(kRenderThreadTestHtml, "<html><body>Test</body></html>",
|
||||||
|
"text/html");
|
||||||
|
|
||||||
|
CreateBrowser(kRenderThreadTestHtml);
|
||||||
|
|
||||||
|
// Time out the test after a reasonable period of time.
|
||||||
|
SetTestTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
||||||
|
bool isLoading,
|
||||||
|
bool canGoBack,
|
||||||
|
bool canGoForward) override {
|
||||||
|
if (!isLoading) {
|
||||||
|
// Return the test in the render process.
|
||||||
|
CefRefPtr<CefProcessMessage> msg =
|
||||||
|
CefProcessMessage::Create(kRenderThreadTestMsg);
|
||||||
|
EXPECT_TRUE(browser->SendProcessMessage(PID_RENDERER, msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OnProcessMessageReceived(
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
CefProcessId source_process,
|
||||||
|
CefRefPtr<CefProcessMessage> message) override {
|
||||||
|
EXPECT_TRUE(browser.get());
|
||||||
|
EXPECT_EQ(PID_RENDERER, source_process);
|
||||||
|
EXPECT_TRUE(message.get());
|
||||||
|
EXPECT_TRUE(message->IsReadOnly());
|
||||||
|
|
||||||
|
const std::string& message_name = message->GetName();
|
||||||
|
EXPECT_STREQ(kRenderThreadTestMsg, message_name.c_str());
|
||||||
|
|
||||||
|
got_message_.yes();
|
||||||
|
|
||||||
|
if (message->GetArgumentList()->GetBool(0))
|
||||||
|
got_success_.yes();
|
||||||
|
|
||||||
|
// Test is complete.
|
||||||
|
DestroyTest();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void DestroyTest() override {
|
||||||
|
EXPECT_TRUE(got_message_);
|
||||||
|
EXPECT_TRUE(got_success_);
|
||||||
|
|
||||||
|
TestHandler::DestroyTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackCallback got_message_;
|
||||||
|
TrackCallback got_success_;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(RenderThreadTestHandler);
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(RenderThreadTestHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Renderer side.
|
||||||
|
class RenderThreadRendererTest : public ClientAppRenderer::Delegate {
|
||||||
|
public:
|
||||||
|
RenderThreadRendererTest() {}
|
||||||
|
|
||||||
|
bool OnProcessMessageReceived(
|
||||||
|
CefRefPtr<ClientAppRenderer> app,
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
CefProcessId source_process,
|
||||||
|
CefRefPtr<CefProcessMessage> message) override {
|
||||||
|
if (message->GetName().ToString() == kRenderThreadTestMsg) {
|
||||||
|
browser_ = browser;
|
||||||
|
EXPECT_FALSE(thread_test_.get());
|
||||||
|
thread_test_ = new SimpleThreadTest(
|
||||||
|
3, base::Closure(),
|
||||||
|
base::Bind(&RenderThreadRendererTest::Done, this));
|
||||||
|
thread_test_->RunTest();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message not handled.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Done() {
|
||||||
|
// Let the call stack unwind before destroying |thread_test_|.
|
||||||
|
CefPostTask(TID_RENDERER,
|
||||||
|
base::Bind(&RenderThreadRendererTest::DestroyTest, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyTest() {
|
||||||
|
EXPECT_TRUE(thread_test_.get());
|
||||||
|
if (thread_test_) {
|
||||||
|
thread_test_->DestroyTest();
|
||||||
|
thread_test_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the test has failed.
|
||||||
|
bool result = !TestFailed();
|
||||||
|
|
||||||
|
// Return the result to the browser process.
|
||||||
|
CefRefPtr<CefProcessMessage> return_msg =
|
||||||
|
CefProcessMessage::Create(kRenderThreadTestMsg);
|
||||||
|
EXPECT_TRUE(return_msg->GetArgumentList()->SetBool(0, result));
|
||||||
|
EXPECT_TRUE(browser_->SendProcessMessage(PID_BROWSER, return_msg));
|
||||||
|
|
||||||
|
browser_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefBrowser> browser_;
|
||||||
|
scoped_refptr<SimpleThreadTest> thread_test_;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(RenderThreadRendererTest);
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(RenderThreadRendererTest);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST(ThreadTest, CreateFromRenderThread) {
|
||||||
|
CefRefPtr<RenderThreadTestHandler> handler = new RenderThreadTestHandler();
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Entry point for creating request handler renderer test objects.
|
||||||
|
// Called from client_app_delegates.cc.
|
||||||
|
void CreateThreadRendererTests(
|
||||||
|
ClientAppRenderer::DelegateSet& delegates) {
|
||||||
|
delegates.insert(new RenderThreadRendererTest);
|
||||||
|
}
|
@ -694,7 +694,7 @@ class obj_header:
|
|||||||
return obj_analysis([self], value, named)
|
return obj_analysis([self], value, named)
|
||||||
|
|
||||||
def get_defined_structs(self):
|
def get_defined_structs(self):
|
||||||
""" Return a list of names already defined structure names. """
|
""" Return a list of already defined structure names. """
|
||||||
return ['cef_print_info_t', 'cef_window_info_t', 'cef_base_t']
|
return ['cef_print_info_t', 'cef_window_info_t', 'cef_base_t']
|
||||||
|
|
||||||
def get_capi_translations(self):
|
def get_capi_translations(self):
|
||||||
|
@ -90,24 +90,39 @@ def make_capi_header(header, filename):
|
|||||||
classes = header.get_classes(filename)
|
classes = header.get_classes(filename)
|
||||||
|
|
||||||
# identify all includes and forward declarations
|
# identify all includes and forward declarations
|
||||||
all_includes = set([])
|
translated_includes = set([])
|
||||||
|
internal_includes = set([])
|
||||||
all_declares = set([])
|
all_declares = set([])
|
||||||
for cls in classes:
|
for cls in classes:
|
||||||
includes = cls.get_includes()
|
includes = cls.get_includes()
|
||||||
for include in includes:
|
for include in includes:
|
||||||
all_includes.add(include)
|
if include.startswith('base/'):
|
||||||
|
# base/ headers are C++. They should not be included by
|
||||||
|
# translated CEF API headers.
|
||||||
|
raise Exception('Disallowed include of %s.h from %s' % (include, filename))
|
||||||
|
elif include.startswith('internal/'):
|
||||||
|
# internal/ headers may be C or C++. Include them as-is.
|
||||||
|
internal_includes.add(include)
|
||||||
|
else:
|
||||||
|
translated_includes.add(include)
|
||||||
declares = cls.get_forward_declares()
|
declares = cls.get_forward_declares()
|
||||||
for declare in declares:
|
for declare in declares:
|
||||||
all_declares.add(header.get_class(declare).get_capi_name())
|
all_declares.add(header.get_class(declare).get_capi_name())
|
||||||
|
|
||||||
# output includes
|
# output translated includes
|
||||||
if len(all_includes) > 0:
|
if len(translated_includes) > 0:
|
||||||
sorted_includes = sorted(all_includes)
|
sorted_includes = sorted(translated_includes)
|
||||||
for include in sorted_includes:
|
for include in sorted_includes:
|
||||||
result += '#include "include/capi/' + include + '_capi.h"\n'
|
result += '#include "include/capi/' + include + '_capi.h"\n'
|
||||||
else:
|
else:
|
||||||
result += '#include "include/capi/cef_base_capi.h"\n'
|
result += '#include "include/capi/cef_base_capi.h"\n'
|
||||||
|
|
||||||
|
# output internal includes
|
||||||
|
if len(internal_includes) > 0:
|
||||||
|
sorted_includes = sorted(internal_includes)
|
||||||
|
for include in sorted_includes:
|
||||||
|
result += '#include "include/' + include + '.h"\n'
|
||||||
|
|
||||||
result += \
|
result += \
|
||||||
"""
|
"""
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
Reference in New Issue
Block a user