- add sources.
[platform/framework/web/crosswalk.git] / src / ppapi / tests / pp_thread.h
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.
4  */
5
6 #ifndef PPAPI_TESTS_PP_THREAD_H_
7 #define PPAPI_TESTS_PP_THREAD_H_
8
9 #include "ppapi/c/pp_macros.h"
10 #include "ppapi/tests/test_utils.h"
11
12 #if defined(PPAPI_POSIX)
13 #include <pthread.h>
14 #elif defined(PPAPI_OS_WIN)
15 #include <process.h>
16 #include <windows.h>
17 #else
18 #error No thread library detected.
19 #endif
20
21 /**
22  * @file
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.
28  *
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.
34  */
35
36 #if defined(PPAPI_POSIX)
37 typedef pthread_t PP_ThreadType;
38 #elif defined(PPAPI_OS_WIN)
39 typedef uintptr_t PP_ThreadType;
40 #endif
41
42 typedef void (PP_ThreadFunction)(void* data);
43
44 PP_INLINE bool PP_CreateThread(PP_ThreadType* thread,
45                                PP_ThreadFunction function,
46                                void* thread_arg);
47 PP_INLINE void PP_JoinThread(PP_ThreadType thread);
48
49 #if defined(PPAPI_POSIX)
50 /* Because POSIX thread functions return void* and Windows thread functions do
51  * 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
53  * function type on POSIX platforms.
54  */
55 struct PP_ThreadFunctionArgWrapper {
56   void* user_data;
57   PP_ThreadFunction* user_function;
58 };
59
60 PP_INLINE void* PP_POSIXThreadFunctionThunk(void* posix_thread_arg) {
61   PP_ThreadFunctionArgWrapper* arg_wrapper =
62       (PP_ThreadFunctionArgWrapper*)posix_thread_arg;
63   arg_wrapper->user_function(arg_wrapper->user_data);
64   free(posix_thread_arg);
65   return NULL;
66 }
67
68 PP_INLINE bool PP_CreateThread(PP_ThreadType* thread,
69                                PP_ThreadFunction function,
70                                void* thread_arg) {
71   PP_ThreadFunctionArgWrapper* arg_wrapper =
72       (PP_ThreadFunctionArgWrapper*)malloc(sizeof(PP_ThreadFunctionArgWrapper));
73   arg_wrapper->user_function = function;
74   arg_wrapper->user_data = thread_arg;
75   return (pthread_create(thread,
76                          NULL,
77                          PP_POSIXThreadFunctionThunk,
78                          arg_wrapper) == 0);
79 }
80
81 PP_INLINE void PP_JoinThread(PP_ThreadType thread) {
82   void* exit_status;
83   pthread_join(thread, &exit_status);
84 }
85
86 #elif defined(PPAPI_OS_WIN)
87 typedef DWORD (PP_WindowsThreadFunction)(void* data);
88
89 PP_INLINE bool PP_CreateThread(PP_ThreadType* thread,
90                                PP_ThreadFunction function,
91                                void* thread_arg) {
92   if (!thread)
93     return false;
94   *thread = ::_beginthread(function,
95                            0,  /* Use default stack size. */
96                            thread_arg);
97   return (*thread != NULL);
98 }
99
100 PP_INLINE void PP_JoinThread(PP_ThreadType thread) {
101   ::WaitForSingleObject((HANDLE)thread, INFINITE);
102 }
103
104 #endif
105
106
107 /**
108  * @}
109  */
110
111 #endif  /* PPAPI_TESTS_PP_THREAD_H_ */
112