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
3 * found in the LICENSE file.
6 #ifndef PPAPI_TESTS_PP_THREAD_H_
7 #define PPAPI_TESTS_PP_THREAD_H_
9 #include "ppapi/c/pp_macros.h"
10 #include "ppapi/tests/test_utils.h"
12 #if defined(PPAPI_POSIX)
14 #elif defined(PPAPI_OS_WIN)
18 #error No thread library detected.
23 * This file provides platform-independent wrappers around threads. This is for
24 * use by PPAPI wrappers and tests which need to run on multiple platforms to
25 * support both trusted platforms (Windows, Mac, Linux) and untrusted (Native
26 * Client). Apps that use PPAPI only with Native Client should generally use the
27 * Native Client POSIX implementation instead.
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
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
33 * used in ppapi/tests, so is not part of the published API.
36 typedef void (PP_ThreadFunction
)(void* data
);
38 #if defined(PPAPI_POSIX)
39 typedef pthread_t PP_Thread
;
40 #elif defined(PPAPI_OS_WIN)
43 PP_ThreadFunction
* thread_func
;
48 PP_INLINE
bool PP_CreateThread(PP_Thread
* thread
,
49 PP_ThreadFunction function
,
51 PP_INLINE
void PP_JoinThread(PP_Thread thread
);
53 #if defined(PPAPI_POSIX)
54 /* Because POSIX thread functions return void* and Windows thread functions do
55 * not, we make PPAPI thread functions have the least capability (no returns).
56 * This struct wraps the user data & function so that we can use the correct
57 * function type on POSIX platforms.
59 struct PP_ThreadFunctionArgWrapper
{
61 PP_ThreadFunction
* user_function
;
64 PP_INLINE
void* PP_POSIXThreadFunctionThunk(void* posix_thread_arg
) {
65 PP_ThreadFunctionArgWrapper
* arg_wrapper
=
66 (PP_ThreadFunctionArgWrapper
*)posix_thread_arg
;
67 arg_wrapper
->user_function(arg_wrapper
->user_data
);
68 free(posix_thread_arg
);
72 PP_INLINE
bool PP_CreateThread(PP_Thread
* thread
,
73 PP_ThreadFunction function
,
75 PP_ThreadFunctionArgWrapper
* arg_wrapper
=
76 (PP_ThreadFunctionArgWrapper
*)malloc(sizeof(PP_ThreadFunctionArgWrapper
));
77 arg_wrapper
->user_function
= function
;
78 arg_wrapper
->user_data
= thread_arg
;
79 return (pthread_create(thread
,
81 PP_POSIXThreadFunctionThunk
,
85 PP_INLINE
void PP_JoinThread(PP_Thread thread
) {
87 pthread_join(thread
, &exit_status
);
90 #elif defined(PPAPI_OS_WIN)
92 PP_INLINE
unsigned __stdcall
PP_WindowsThreadFunction(void* param
) {
93 PP_Thread
* thread
= reinterpret_cast<PP_Thread
*>(param
);
94 thread
->thread_func(thread
->thread_arg
);
98 PP_INLINE
bool PP_CreateThread(PP_Thread
* thread
,
99 PP_ThreadFunction function
,
103 thread
->thread_func
= function
;
104 thread
->thread_arg
= thread_arg
;
105 uintptr_t raw_handle
= ::_beginthreadex(NULL
,
106 0, /* Use default stack size. */
107 &PP_WindowsThreadFunction
,
111 thread
->handle
= reinterpret_cast<HANDLE
>(raw_handle
);
112 return (thread
->handle
!= NULL
);
115 PP_INLINE
void PP_JoinThread(PP_Thread thread
) {
116 ::WaitForSingleObject(thread
.handle
, INFINITE
);
117 ::CloseHandle(thread
.handle
);
127 #endif /* PPAPI_TESTS_PP_THREAD_H_ */