Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 /* Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 * Use of this source code is governed by a BSD-style license that can be | 2 * Use of this source code is governed by a BSD-style license that can be |
| 3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
| 4 */ | 4 */ |
| 5 | 5 |
| 6 #ifndef PPAPI_TESTS_PP_THREAD_H_ | 6 #ifndef PPAPI_TESTS_PP_THREAD_H_ |
| 7 #define PPAPI_TESTS_PP_THREAD_H_ | 7 #define PPAPI_TESTS_PP_THREAD_H_ |
| 8 | 8 |
| 9 #include "ppapi/c/pp_macros.h" | 9 #include "ppapi/c/pp_macros.h" |
| 10 #include "ppapi/tests/test_utils.h" | 10 #include "ppapi/tests/test_utils.h" |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 * Client). Apps that use PPAPI only with Native Client should generally use the | 26 * Client). Apps that use PPAPI only with Native Client should generally use the |
| 27 * Native Client POSIX implementation instead. | 27 * Native Client POSIX implementation instead. |
| 28 * | 28 * |
| 29 * TODO(dmichael): Move this file to ppapi/c and delete this comment, if we end | 29 * TODO(dmichael): Move this file to ppapi/c and delete this comment, if we end |
| 30 * up needing platform independent threads in PPAPI C or C++. This file was | 30 * up needing platform independent threads in PPAPI C or C++. This file was |
| 31 * written using inline functions and PPAPI naming conventions with the intent | 31 * written using inline functions and PPAPI naming conventions with the intent |
| 32 * of making it possible to put it in to ppapi/c. Currently, however, it's only | 32 * of making it possible to put it in to ppapi/c. Currently, however, it's only |
| 33 * used in ppapi/tests, so is not part of the published API. | 33 * used in ppapi/tests, so is not part of the published API. |
| 34 */ | 34 */ |
| 35 | 35 |
| 36 typedef void (PP_ThreadFunction)(void* data); | |
| 37 | |
| 36 #if defined(PPAPI_POSIX) | 38 #if defined(PPAPI_POSIX) |
| 37 typedef pthread_t PP_ThreadType; | 39 typedef pthread_t PP_Thread; |
| 38 #elif defined(PPAPI_OS_WIN) | 40 #elif defined(PPAPI_OS_WIN) |
| 39 typedef uintptr_t PP_ThreadType; | 41 struct PP_Thread { |
| 42 HANDLE handle; | |
| 43 PP_ThreadFunction* thread_func; | |
| 44 void* thread_arg; | |
| 45 }; | |
| 40 #endif | 46 #endif |
| 41 | 47 |
| 42 typedef void (PP_ThreadFunction)(void* data); | 48 PP_INLINE bool PP_CreateThread(PP_Thread* thread, |
| 43 | |
| 44 PP_INLINE bool PP_CreateThread(PP_ThreadType* thread, | |
| 45 PP_ThreadFunction function, | 49 PP_ThreadFunction function, |
| 46 void* thread_arg); | 50 void* thread_arg); |
| 47 PP_INLINE void PP_JoinThread(PP_ThreadType thread); | 51 PP_INLINE void PP_JoinThread(PP_Thread thread); |
| 48 | 52 |
| 49 #if defined(PPAPI_POSIX) | 53 #if defined(PPAPI_POSIX) |
| 50 /* Because POSIX thread functions return void* and Windows thread functions do | 54 /* Because POSIX thread functions return void* and Windows thread functions do |
| 51 * not, we make PPAPI thread functions have the least capability (no returns). | 55 * not, we make PPAPI thread functions have the least capability (no returns). |
| 52 * This struct wraps the user data & function so that we can use the correct | 56 * This struct wraps the user data & function so that we can use the correct |
| 53 * function type on POSIX platforms. | 57 * function type on POSIX platforms. |
| 54 */ | 58 */ |
| 55 struct PP_ThreadFunctionArgWrapper { | 59 struct PP_ThreadFunctionArgWrapper { |
| 56 void* user_data; | 60 void* user_data; |
| 57 PP_ThreadFunction* user_function; | 61 PP_ThreadFunction* user_function; |
| 58 }; | 62 }; |
| 59 | 63 |
| 60 PP_INLINE void* PP_POSIXThreadFunctionThunk(void* posix_thread_arg) { | 64 PP_INLINE void* PP_POSIXThreadFunctionThunk(void* posix_thread_arg) { |
| 61 PP_ThreadFunctionArgWrapper* arg_wrapper = | 65 PP_ThreadFunctionArgWrapper* arg_wrapper = |
| 62 (PP_ThreadFunctionArgWrapper*)posix_thread_arg; | 66 (PP_ThreadFunctionArgWrapper*)posix_thread_arg; |
| 63 arg_wrapper->user_function(arg_wrapper->user_data); | 67 arg_wrapper->user_function(arg_wrapper->user_data); |
| 64 free(posix_thread_arg); | 68 free(posix_thread_arg); |
| 65 return NULL; | 69 return NULL; |
| 66 } | 70 } |
| 67 | 71 |
| 68 PP_INLINE bool PP_CreateThread(PP_ThreadType* thread, | 72 PP_INLINE bool PP_CreateThread(PP_Thread* thread, |
| 69 PP_ThreadFunction function, | 73 PP_ThreadFunction function, |
| 70 void* thread_arg) { | 74 void* thread_arg) { |
| 71 PP_ThreadFunctionArgWrapper* arg_wrapper = | 75 PP_ThreadFunctionArgWrapper* arg_wrapper = |
| 72 (PP_ThreadFunctionArgWrapper*)malloc(sizeof(PP_ThreadFunctionArgWrapper)); | 76 (PP_ThreadFunctionArgWrapper*)malloc(sizeof(PP_ThreadFunctionArgWrapper)); |
| 73 arg_wrapper->user_function = function; | 77 arg_wrapper->user_function = function; |
| 74 arg_wrapper->user_data = thread_arg; | 78 arg_wrapper->user_data = thread_arg; |
| 75 return (pthread_create(thread, | 79 return (pthread_create(thread, |
| 76 NULL, | 80 NULL, |
| 77 PP_POSIXThreadFunctionThunk, | 81 PP_POSIXThreadFunctionThunk, |
| 78 arg_wrapper) == 0); | 82 arg_wrapper) == 0); |
| 79 } | 83 } |
| 80 | 84 |
| 81 PP_INLINE void PP_JoinThread(PP_ThreadType thread) { | 85 PP_INLINE void PP_JoinThread(PP_Thread thread) { |
| 82 void* exit_status; | 86 void* exit_status; |
| 83 pthread_join(thread, &exit_status); | 87 pthread_join(thread, &exit_status); |
| 84 } | 88 } |
| 85 | 89 |
| 86 #elif defined(PPAPI_OS_WIN) | 90 #elif defined(PPAPI_OS_WIN) |
| 87 typedef DWORD (PP_WindowsThreadFunction)(void* data); | |
| 88 | 91 |
| 89 PP_INLINE bool PP_CreateThread(PP_ThreadType* thread, | 92 PP_INLINE unsigned __stdcall PP_WindowsThreadFunction(void* param) { |
| 93 PP_Thread* params = reinterpret_cast<PP_Thread*>(param); | |
|
bbudge
2014/09/11 14:06:01
nit: name this 'thread'?
| |
| 94 params->thread_func(params->thread_arg); | |
| 95 return 0; | |
| 96 } | |
| 97 | |
| 98 PP_INLINE bool PP_CreateThread(PP_Thread* thread, | |
| 90 PP_ThreadFunction function, | 99 PP_ThreadFunction function, |
| 91 void* thread_arg) { | 100 void* thread_arg) { |
| 92 if (!thread) | 101 if (!thread) |
| 93 return false; | 102 return false; |
| 94 *thread = ::_beginthread(function, | 103 thread->thread_func = function; |
| 95 0, /* Use default stack size. */ | 104 thread->thread_arg = thread_arg; |
| 96 thread_arg); | 105 uintptr_t raw_handle = ::_beginthreadex(NULL, |
| 97 return (*thread != NULL); | 106 0, /* Use default stack size. */ |
| 107 &PP_WindowsThreadFunction, | |
| 108 thread, | |
| 109 0, | |
| 110 NULL); | |
| 111 thread->handle = reinterpret_cast<HANDLE>(raw_handle); | |
| 112 return (thread->handle != NULL); | |
| 98 } | 113 } |
| 99 | 114 |
| 100 PP_INLINE void PP_JoinThread(PP_ThreadType thread) { | 115 PP_INLINE void PP_JoinThread(PP_Thread thread) { |
| 101 ::WaitForSingleObject((HANDLE)thread, INFINITE); | 116 ::WaitForSingleObject(thread.handle, INFINITE); |
| 117 ::CloseHandle(thread.handle); | |
| 102 } | 118 } |
| 103 | 119 |
| 104 #endif | 120 #endif |
| 105 | 121 |
| 106 | 122 |
| 107 /** | 123 /** |
| 108 * @} | 124 * @} |
| 109 */ | 125 */ |
| 110 | 126 |
| 111 #endif /* PPAPI_TESTS_PP_THREAD_H_ */ | 127 #endif /* PPAPI_TESTS_PP_THREAD_H_ */ |
| 112 | 128 |
| OLD | NEW |