| // Copyright (c) 2012 The Chromium 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 "ppapi/utility/threading/simple_thread.h" |
| |
| #ifdef WIN32 |
| #include <windows.h> |
| #endif |
| |
| namespace pp { |
| |
| namespace { |
| |
| // Use 2MB default stack size for Native Client, otherwise use system default. |
| #if defined(__native_client__) |
| const size_t kDefaultStackSize = 2 * 1024 * 1024; |
| #else |
| const size_t kDefaultStackSize = 0; |
| #endif |
| |
| |
| struct ThreadData { |
| MessageLoop message_loop; |
| |
| SimpleThread::ThreadFunc func; |
| void* user_data; |
| }; |
| |
| #ifdef WIN32 |
| DWORD WINAPI RunThread(void* void_data) { |
| #else |
| void* RunThread(void* void_data) { |
| #endif |
| ThreadData* data = static_cast<ThreadData*>(void_data); |
| data->message_loop.AttachToCurrentThread(); |
| |
| if (data->func) |
| data->func(data->message_loop, data->user_data); |
| else |
| data->message_loop.Run(); |
| |
| delete data; |
| return NULL; |
| } |
| |
| } // namespace |
| |
| SimpleThread::SimpleThread(const InstanceHandle& instance) |
| : instance_(instance), |
| message_loop_(instance), |
| stacksize_(kDefaultStackSize), |
| thread_(0) { |
| } |
| |
| SimpleThread::SimpleThread(const InstanceHandle& instance, |
| size_t stacksize) |
| : instance_(instance), |
| message_loop_(instance), |
| stacksize_(stacksize), |
| thread_(0) { |
| } |
| |
| SimpleThread::~SimpleThread() { |
| Join(); |
| } |
| |
| bool SimpleThread::Start() { |
| return StartWithFunction(NULL, NULL); |
| } |
| |
| bool SimpleThread::Join() { |
| if (!thread_) |
| return false; |
| |
| message_loop_.PostQuit(true); |
| |
| #ifdef WIN32 |
| DWORD result = WaitForSingleObject(thread_, INFINITE); |
| CloseHandle(thread_); |
| thread_ = 0; |
| return result == WAIT_OBJECT_0; |
| |
| #else |
| void* retval; |
| int result = pthread_join(thread_, &retval); |
| thread_ = 0; |
| return result == 0; |
| #endif |
| } |
| |
| bool SimpleThread::StartWithFunction(ThreadFunc func, void* user_data) { |
| if (thread_) |
| return false; |
| |
| ThreadData* data = new ThreadData; |
| data->message_loop = message_loop_; |
| data->func = func; |
| data->user_data = user_data; |
| |
| #ifdef WIN32 |
| thread_ = CreateThread(NULL, stacksize_, &RunThread, data, 0, NULL); |
| if (!thread_) { |
| #else |
| pthread_attr_t attr; |
| pthread_attr_init(&attr); |
| int setval = 0; |
| if (stacksize_ > 0) |
| setval = pthread_attr_setstacksize(&attr, stacksize_); |
| if (setval != 0 || pthread_create(&thread_, &attr, &RunThread, data) != 0) { |
| #endif |
| delete data; |
| return false; |
| } |
| return true; |
| } |
| |
| } // namespace pp |