• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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 #include "ppapi/utility/threading/simple_thread.h"
6 
7 #ifdef WIN32
8 #include <windows.h>
9 #endif
10 
11 namespace pp {
12 
13 namespace {
14 
15 // Use 2MB default stack size for Native Client, otherwise use system default.
16 #if defined(__native_client__)
17 const size_t kDefaultStackSize = 2 * 1024 * 1024;
18 #else
19 const size_t kDefaultStackSize = 0;
20 #endif
21 
22 
23 struct ThreadData {
24   MessageLoop message_loop;
25 
26   SimpleThread::ThreadFunc func;
27   void* user_data;
28 };
29 
30 #ifdef WIN32
RunThread(void * void_data)31 DWORD WINAPI RunThread(void* void_data) {
32 #else
33 void* RunThread(void* void_data) {
34 #endif
35   ThreadData* data = static_cast<ThreadData*>(void_data);
36   data->message_loop.AttachToCurrentThread();
37 
38   if (data->func)
39     data->func(data->message_loop, data->user_data);
40   else
41     data->message_loop.Run();
42 
43   delete data;
44   return NULL;
45 }
46 
47 }   // namespace
48 
SimpleThread(const InstanceHandle & instance)49 SimpleThread::SimpleThread(const InstanceHandle& instance)
50     : instance_(instance),
51       message_loop_(instance),
52       stacksize_(kDefaultStackSize),
53       thread_(0) {
54 }
55 
SimpleThread(const InstanceHandle & instance,size_t stacksize)56 SimpleThread::SimpleThread(const InstanceHandle& instance,
57                            size_t stacksize)
58     : instance_(instance),
59       message_loop_(instance),
60       stacksize_(stacksize),
61       thread_(0) {
62 }
63 
~SimpleThread()64 SimpleThread::~SimpleThread() {
65   Join();
66 }
67 
Start()68 bool SimpleThread::Start() {
69   return StartWithFunction(NULL, NULL);
70 }
71 
Join()72 bool SimpleThread::Join() {
73   if (!thread_)
74     return false;
75 
76   message_loop_.PostQuit(true);
77 
78 #ifdef WIN32
79   DWORD result = WaitForSingleObject(thread_, INFINITE);
80   CloseHandle(thread_);
81   thread_ = 0;
82   return result == WAIT_OBJECT_0;
83 
84 #else
85   void* retval;
86   int result = pthread_join(thread_, &retval);
87   thread_ = 0;
88   return result == 0;
89 #endif
90 }
91 
StartWithFunction(ThreadFunc func,void * user_data)92 bool SimpleThread::StartWithFunction(ThreadFunc func, void* user_data) {
93   if (thread_)
94     return false;
95 
96   ThreadData* data = new ThreadData;
97   data->message_loop = message_loop_;
98   data->func = func;
99   data->user_data = user_data;
100 
101 #ifdef WIN32
102   thread_ = CreateThread(NULL, stacksize_, &RunThread, data, 0, NULL);
103   if (!thread_) {
104 #else
105   pthread_attr_t attr;
106   pthread_attr_init(&attr);
107   int setval = 0;
108   if (stacksize_ > 0)
109     setval = pthread_attr_setstacksize(&attr, stacksize_);
110   if (setval != 0 || pthread_create(&thread_, &attr, &RunThread, data) != 0) {
111 #endif
112     delete data;
113     return false;
114   }
115   return true;
116 }
117 
118 }  // namespace pp
119