// 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