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,17 +45,12 @@ 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. | ||||||
|     retval_ = test_suite_->Run(); |   test_state->retval_ = test_state->test_suite_->Run(); | ||||||
|  |  | ||||||
|   // Wait for all browsers to exit. |   // Wait for all browsers to exit. | ||||||
|   while (TestHandler::HasBrowser()) |   while (TestHandler::HasBrowser()) | ||||||
| @@ -58,20 +58,15 @@ class CefTestThread : public base::Thread { | |||||||
|  |  | ||||||
|   // 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