Change the thread interface in runtime/platform and use it starting all threads
The platform thread interface (dart::thread) is now refactored to an all static interface as suggested by iposva@ and asiva@. Use this interface for running all threads in the VM. R=ager@google.com, iposva@google.com BUG= TEST= Review URL: https://chromiumcodereview.appspot.com//9141005 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@3830 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
@@ -51,12 +51,6 @@
|
||||
'set_test.cc',
|
||||
'thread.h',
|
||||
'thread_pool.cc',
|
||||
'thread_pool_linux.cc',
|
||||
'thread_pool_linux.h',
|
||||
'thread_pool_macos.cc',
|
||||
'thread_pool_macos.h',
|
||||
'thread_pool_test.cc',
|
||||
'thread_pool_win.cc',
|
||||
'thread_pool_win.h',
|
||||
],
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#include "bin/eventhandler.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <pthread.h>
|
||||
@@ -10,7 +12,6 @@
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bin/eventhandler.h"
|
||||
#include "bin/fdutils.h"
|
||||
#include "bin/hashmap.h"
|
||||
#include "platform/utils.h"
|
||||
@@ -339,11 +340,12 @@ void EventHandlerImplementation::HandleTimeout() {
|
||||
}
|
||||
|
||||
|
||||
void* EventHandlerImplementation::Poll(void* args) {
|
||||
void EventHandlerImplementation::Poll(uword args) {
|
||||
intptr_t pollfds_size;
|
||||
struct pollfd* pollfds;
|
||||
EventHandlerImplementation* handler =
|
||||
reinterpret_cast<EventHandlerImplementation*>(args);
|
||||
ASSERT(handler != NULL);
|
||||
while (1) {
|
||||
pollfds = handler->GetPollFds(&pollfds_size);
|
||||
intptr_t millis = handler->GetTimeout();
|
||||
@@ -359,18 +361,14 @@ void* EventHandlerImplementation::Poll(void* args) {
|
||||
}
|
||||
free(pollfds);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void EventHandlerImplementation::StartEventHandler() {
|
||||
pthread_t handler_thread;
|
||||
int result = pthread_create(&handler_thread,
|
||||
NULL,
|
||||
&EventHandlerImplementation::Poll,
|
||||
this);
|
||||
int result = dart::Thread::Start(&EventHandlerImplementation::Poll,
|
||||
reinterpret_cast<uword>(this));
|
||||
if (result != 0) {
|
||||
FATAL("Create start event handler thread");
|
||||
FATAL1("Failed to start event handler thread %d", result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ class EventHandlerImplementation {
|
||||
struct pollfd* GetPollFds(intptr_t* size);
|
||||
void HandleEvents(struct pollfd* pollfds, int pollfds_size, int result_size);
|
||||
void HandleTimeout();
|
||||
static void* Poll(void* args);
|
||||
static void Poll(uword args);
|
||||
void WakeupHandler(intptr_t id, Dart_Port dart_port, int64_t data);
|
||||
void HandleInterruptFd();
|
||||
void SetPort(intptr_t fd, Dart_Port dart_port, intptr_t mask);
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#include "bin/eventhandler.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <pthread.h>
|
||||
@@ -10,7 +12,6 @@
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bin/eventhandler.h"
|
||||
#include "bin/fdutils.h"
|
||||
#include "bin/hashmap.h"
|
||||
#include "platform/utils.h"
|
||||
@@ -337,11 +338,12 @@ void EventHandlerImplementation::HandleTimeout() {
|
||||
}
|
||||
|
||||
|
||||
void* EventHandlerImplementation::Poll(void* args) {
|
||||
void EventHandlerImplementation::Poll(uword args) {
|
||||
intptr_t pollfds_size;
|
||||
struct pollfd* pollfds;
|
||||
EventHandlerImplementation* handler =
|
||||
reinterpret_cast<EventHandlerImplementation*>(args);
|
||||
ASSERT(handler != NULL);
|
||||
while (1) {
|
||||
pollfds = handler->GetPollFds(&pollfds_size);
|
||||
intptr_t millis = handler->GetTimeout();
|
||||
@@ -357,18 +359,14 @@ void* EventHandlerImplementation::Poll(void* args) {
|
||||
}
|
||||
free(pollfds);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void EventHandlerImplementation::StartEventHandler() {
|
||||
pthread_t handler_thread;
|
||||
int result = pthread_create(&handler_thread,
|
||||
NULL,
|
||||
&EventHandlerImplementation::Poll,
|
||||
this);
|
||||
int result = dart::Thread::Start(&EventHandlerImplementation::Poll,
|
||||
reinterpret_cast<uword>(this));
|
||||
if (result != 0) {
|
||||
FATAL("Create start event handler thread");
|
||||
FATAL1("Failed to start event handler thread %d", result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ class EventHandlerImplementation {
|
||||
struct pollfd* GetPollFds(intptr_t* size);
|
||||
void HandleEvents(struct pollfd* pollfds, int pollfds_size, int result_size);
|
||||
void HandleTimeout();
|
||||
static void* Poll(void* args);
|
||||
static void Poll(uword args);
|
||||
void WakeupHandler(intptr_t id, Dart_Port dart_port, int64_t data);
|
||||
void HandleInterruptFd();
|
||||
void SetPort(intptr_t fd, Dart_Port dart_port, intptr_t mask);
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#include "bin/eventhandler.h"
|
||||
|
||||
#include <process.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <mswsock.h>
|
||||
|
||||
#include "bin/builtin.h"
|
||||
#include "bin/eventhandler.h"
|
||||
#include "bin/socket.h"
|
||||
|
||||
|
||||
@@ -823,9 +824,10 @@ void EventHandlerImplementation::SendData(intptr_t id,
|
||||
}
|
||||
|
||||
|
||||
static unsigned int __stdcall EventHandlerThread(void* args) {
|
||||
static void EventHandlerThread(uword args) {
|
||||
EventHandlerImplementation* handler =
|
||||
reinterpret_cast<EventHandlerImplementation*>(args);
|
||||
ASSERT(handler != NULL);
|
||||
while (true) {
|
||||
DWORD bytes;
|
||||
ULONG_PTR key;
|
||||
@@ -877,11 +879,10 @@ static unsigned int __stdcall EventHandlerThread(void* args) {
|
||||
|
||||
|
||||
void EventHandlerImplementation::StartEventHandler() {
|
||||
uint32_t tid;
|
||||
uintptr_t thread_handle =
|
||||
_beginthreadex(NULL, 32 * 1024, EventHandlerThread, this, 0, &tid);
|
||||
if (thread_handle == -1) {
|
||||
FATAL("Failed to start event handler thread");
|
||||
int result = dart::Thread::Start(EventHandlerThread,
|
||||
reinterpret_cast<uword>(this));
|
||||
if (result != 0) {
|
||||
FATAL1("Failed to start event handler thread %d", result);
|
||||
}
|
||||
|
||||
// Initialize Winsock32
|
||||
|
||||
@@ -120,7 +120,10 @@ class ExitCodeHandler {
|
||||
|
||||
// Start thread that polls the pipe and handles process exits when
|
||||
// data is received on the pipe.
|
||||
new dart::Thread(ExitCodeHandlerEntry, sig_chld_fds_[0]);
|
||||
result = dart::Thread::Start(ExitCodeHandlerEntry, sig_chld_fds_[0]);
|
||||
if (result != 0) {
|
||||
FATAL1("Failed to start exit code handler worker thread %d", result);
|
||||
}
|
||||
|
||||
// Mark write end non-blocking.
|
||||
FDUtils::SetNonBlocking(sig_chld_fds_[1]);
|
||||
|
||||
@@ -119,7 +119,10 @@ class ExitCodeHandler {
|
||||
|
||||
// Start thread that polls the pipe and handles process exits when
|
||||
// data is received on the pipe.
|
||||
new dart::Thread(ExitCodeHandlerEntry, sig_chld_fds_[0]);
|
||||
result = dart::Thread::Start(ExitCodeHandlerEntry, sig_chld_fds_[0]);
|
||||
if (result != 0) {
|
||||
FATAL1("Failed to start exit code handler worker thread %d", result);
|
||||
}
|
||||
|
||||
// Mark write end non-blocking.
|
||||
FDUtils::SetNonBlocking(sig_chld_fds_[1]);
|
||||
|
||||
@@ -63,7 +63,36 @@ Task ThreadPool::WaitForTask() {
|
||||
}
|
||||
|
||||
|
||||
void* ThreadPool::Main(void* args) {
|
||||
void ThreadPool::Start() {
|
||||
MonitorLocker monitor(&monitor_);
|
||||
for (int i = 0; i < size_; i++) {
|
||||
int result = dart::Thread::Start(&ThreadPool::Main,
|
||||
reinterpret_cast<uword>(this));
|
||||
if (result != 0) {
|
||||
FATAL1("Failed to start thread pool thread %d", result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ThreadPool::Shutdown() {
|
||||
terminate_ = true;
|
||||
queue_.Shutdown();
|
||||
MonitorLocker monitor(&monitor_);
|
||||
while (size_ > 0) {
|
||||
monitor.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ThreadPool::ThreadTerminated() {
|
||||
MonitorLocker monitor(&monitor_);
|
||||
size_--;
|
||||
monitor.Notify();
|
||||
}
|
||||
|
||||
|
||||
void ThreadPool::Main(uword args) {
|
||||
if (Dart_IsVMFlagSet("trace_thread_pool")) {
|
||||
printf("Thread pool thread started\n");
|
||||
}
|
||||
@@ -73,8 +102,8 @@ void* ThreadPool::Main(void* args) {
|
||||
printf("Waiting for task\n");
|
||||
}
|
||||
Task task = pool->WaitForTask();
|
||||
if (pool->terminate_) return NULL;
|
||||
if (pool->terminate_) break;
|
||||
(*(pool->task_handler_))(task);
|
||||
}
|
||||
return NULL;
|
||||
pool->ThreadTerminated();
|
||||
};
|
||||
|
||||
@@ -9,18 +9,6 @@
|
||||
#include "platform/globals.h"
|
||||
#include "platform/thread.h"
|
||||
|
||||
// Declare the OS-specific types ahead of defining the generic classes.
|
||||
#if defined(TARGET_OS_LINUX)
|
||||
#include "bin/thread_pool_linux.h"
|
||||
#elif defined(TARGET_OS_MACOS)
|
||||
#include "bin/thread_pool_macos.h"
|
||||
#elif defined(TARGET_OS_WINDOWS)
|
||||
#include "bin/thread_pool_win.h"
|
||||
#else
|
||||
#error Unknown target os.
|
||||
#endif
|
||||
|
||||
|
||||
typedef void* Task;
|
||||
|
||||
|
||||
@@ -74,18 +62,20 @@ class ThreadPool {
|
||||
|
||||
void InsertTask(Task task);
|
||||
|
||||
void ThreadTerminated();
|
||||
|
||||
private:
|
||||
Task WaitForTask();
|
||||
|
||||
static void* Main(void* args);
|
||||
static void Main(uword args);
|
||||
|
||||
TaskQueue queue_;
|
||||
// TODO(sgjesse): Move the monitor in TaskQueue to ThreadPool and
|
||||
// obtain it for updating terminate_.
|
||||
dart::Monitor monitor_;
|
||||
bool terminate_;
|
||||
int size_; // Number of threads.
|
||||
TaskHandler task_handler_;
|
||||
ThreadPoolData data_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ThreadPool);
|
||||
};
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "bin/thread_pool.h"
|
||||
|
||||
void ThreadPool::Start() {
|
||||
pthread_t* threads
|
||||
= reinterpret_cast<pthread_t*>(calloc(size_, sizeof(pthread_t*))); // NOLINT
|
||||
data_.set_threads(threads);
|
||||
for (int i = 0; i < size_; i++) {
|
||||
pthread_t handler_thread;
|
||||
int result = pthread_create(&handler_thread,
|
||||
NULL,
|
||||
&ThreadPool::Main,
|
||||
this);
|
||||
if (result != 0) {
|
||||
FATAL("Create and start thread pool thread");
|
||||
}
|
||||
data_.threads()[i] = handler_thread;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ThreadPool::Shutdown() {
|
||||
terminate_ = true;
|
||||
queue_.Shutdown();
|
||||
for (int i = 0; i < size_; i++) {
|
||||
pthread_join(data_.threads()[i], NULL);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#ifndef BIN_THREAD_POOL_LINUX_H_
|
||||
#define BIN_THREAD_POOL_LINUX_H_
|
||||
|
||||
#if !defined(BIN_THREAD_POOL_H_)
|
||||
#error Do not include thread_pool_linux.h directly; use thread_pool.h instead.
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "platform/globals.h"
|
||||
|
||||
|
||||
class ThreadPoolData {
|
||||
private:
|
||||
ThreadPoolData() {}
|
||||
~ThreadPoolData() {}
|
||||
|
||||
pthread_t* threads() { return threads_; }
|
||||
void set_threads(pthread_t* threads) { threads_ = threads; }
|
||||
|
||||
pthread_t* threads_;
|
||||
|
||||
friend class ThreadPool;
|
||||
|
||||
DISALLOW_ALLOCATION();
|
||||
DISALLOW_COPY_AND_ASSIGN(ThreadPoolData);
|
||||
};
|
||||
|
||||
#endif // BIN_THREAD_POOL_LINUX_H_
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "bin/thread_pool.h"
|
||||
|
||||
void ThreadPool::Start() {
|
||||
pthread_t* threads
|
||||
= reinterpret_cast<pthread_t*>(calloc(size_, sizeof(pthread_t*))); // NOLINT
|
||||
data_.set_threads(threads);
|
||||
for (int i = 0; i < size_; i++) {
|
||||
pthread_t handler_thread;
|
||||
int result = pthread_create(&handler_thread,
|
||||
NULL,
|
||||
&ThreadPool::Main,
|
||||
this);
|
||||
if (result != 0) {
|
||||
FATAL("Create and start thread pool thread");
|
||||
}
|
||||
data_.threads()[i] = handler_thread;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ThreadPool::Shutdown() {
|
||||
terminate_ = true;
|
||||
queue_.Shutdown();
|
||||
for (int i = 0; i < size_; i++) {
|
||||
pthread_join(data_.threads()[i], NULL);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#ifndef BIN_THREAD_POOL_MACOS_H_
|
||||
#define BIN_THREAD_POOL_MACOS_H_
|
||||
|
||||
#if !defined(BIN_THREAD_POOL_H_)
|
||||
#error Do not include thread_pool_macos.h directly; use thread_pool.h instead.
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "platform/globals.h"
|
||||
|
||||
|
||||
class ThreadPoolData {
|
||||
private:
|
||||
ThreadPoolData() {}
|
||||
~ThreadPoolData() {}
|
||||
|
||||
pthread_t* threads() { return threads_; }
|
||||
void set_threads(pthread_t* threads) { threads_ = threads; }
|
||||
|
||||
pthread_t* threads_;
|
||||
|
||||
friend class ThreadPool;
|
||||
|
||||
DISALLOW_ALLOCATION();
|
||||
DISALLOW_COPY_AND_ASSIGN(ThreadPoolData);
|
||||
};
|
||||
|
||||
#endif // BIN_THREAD_POOL_MACOS_H_
|
||||
@@ -1,14 +0,0 @@
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#include "bin/thread_pool.h"
|
||||
|
||||
void ThreadPool::Start() {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
|
||||
void ThreadPool::Shutdown() {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#ifndef BIN_THREAD_POOL_WIN_H_
|
||||
#define BIN_THREAD_POOL_WIN_H_
|
||||
|
||||
#if !defined(BIN_THREAD_POOL_H_)
|
||||
#error Do not include thread_pool_win.h directly; use thread_pool.h instead.
|
||||
#endif
|
||||
|
||||
#include "platform/globals.h"
|
||||
|
||||
class ThreadPoolData {
|
||||
private:
|
||||
static const int kMaxThreadPoolSize = 16;
|
||||
|
||||
ThreadPoolData() { UNIMPLEMENTED(); }
|
||||
~ThreadPoolData() {}
|
||||
|
||||
friend class ThreadPool;
|
||||
|
||||
DISALLOW_ALLOCATION();
|
||||
DISALLOW_COPY_AND_ASSIGN(ThreadPoolData);
|
||||
};
|
||||
|
||||
#endif // BIN_THREAD_POOL_WIN_H_
|
||||
@@ -299,7 +299,10 @@ DEFINE_NATIVE_ENTRY(IsolateNatives_start, 2) {
|
||||
strdup(library_url),
|
||||
strdup(class_name),
|
||||
port_id));
|
||||
new Thread(RunIsolate, data);
|
||||
int result = Thread::Start(RunIsolate, data);
|
||||
if (result != 0) {
|
||||
FATAL1("Failed to start isolate thread %d", result);
|
||||
}
|
||||
} else {
|
||||
// Error spawning the isolate, maybe due to initialization errors or
|
||||
// errors while loading the application into spawned isolate, shut
|
||||
|
||||
@@ -22,17 +22,12 @@ namespace dart {
|
||||
|
||||
class Thread {
|
||||
public:
|
||||
// Function to be called on thread start.
|
||||
typedef void (*ThreadStartFunction) (uword parameter);
|
||||
|
||||
// TODO(iposva): Define the proper interface for spawning and killing threads.
|
||||
Thread(ThreadStartFunction function, uword parameters);
|
||||
~Thread();
|
||||
|
||||
private:
|
||||
ThreadData data_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Thread);
|
||||
// Start a thread running the specified function. Returns 0 if the
|
||||
// thread started successfuly and a system specific error code if
|
||||
// the thread failed to start.
|
||||
static int Start(ThreadStartFunction function, uword parameters);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -17,6 +17,19 @@ namespace dart {
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
#define RETURN_ON_PTHREAD_FAILURE(result) \
|
||||
if (result != 0) { \
|
||||
fprintf(stderr, "%s:%d: pthread error: %d (%s)\n", \
|
||||
__FILE__, __LINE__, result, strerror(result)); \
|
||||
return result; \
|
||||
}
|
||||
#else
|
||||
#define RETURN_ON_PTHREAD_FAILURE(result) \
|
||||
if (result != 0) return result;
|
||||
#endif
|
||||
|
||||
|
||||
static void ComputeTimeSpec(struct timespec* ts, int64_t millis) {
|
||||
int64_t secs = millis / kMillisecondsPerSecond;
|
||||
int64_t nanos =
|
||||
@@ -35,18 +48,15 @@ static void ComputeTimeSpec(struct timespec* ts, int64_t millis) {
|
||||
class ThreadStartData {
|
||||
public:
|
||||
ThreadStartData(Thread::ThreadStartFunction function,
|
||||
uword parameter,
|
||||
Thread* thread)
|
||||
: function_(function), parameter_(parameter), thread_(thread) {}
|
||||
uword parameter)
|
||||
: function_(function), parameter_(parameter) {}
|
||||
|
||||
Thread::ThreadStartFunction function() const { return function_; }
|
||||
uword parameter() const { return parameter_; }
|
||||
Thread* thread() const { return thread_; }
|
||||
|
||||
private:
|
||||
Thread::ThreadStartFunction function_;
|
||||
uword parameter_;
|
||||
Thread* thread_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ThreadStartData);
|
||||
};
|
||||
@@ -60,47 +70,36 @@ static void* ThreadStart(void* data_ptr) {
|
||||
|
||||
Thread::ThreadStartFunction function = data->function();
|
||||
uword parameter = data->parameter();
|
||||
Thread* thread = data->thread();
|
||||
delete data;
|
||||
|
||||
// Call the supplied thread start function handing it its parameters.
|
||||
function(parameter);
|
||||
|
||||
// When the function returns here, make sure that the thread is deleted.
|
||||
delete thread;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Thread::Thread(ThreadStartFunction function, uword parameter) {
|
||||
int Thread::Start(ThreadStartFunction function, uword parameter) {
|
||||
pthread_attr_t attr;
|
||||
int result = pthread_attr_init(&attr);
|
||||
VALIDATE_PTHREAD_RESULT(result);
|
||||
RETURN_ON_PTHREAD_FAILURE(result);
|
||||
|
||||
result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
VALIDATE_PTHREAD_RESULT(result);
|
||||
RETURN_ON_PTHREAD_FAILURE(result);
|
||||
|
||||
result = pthread_attr_setstacksize(&attr, 1024 * KB);
|
||||
VALIDATE_PTHREAD_RESULT(result);
|
||||
RETURN_ON_PTHREAD_FAILURE(result);
|
||||
|
||||
ThreadStartData* data = new ThreadStartData(function, parameter, this);
|
||||
ThreadStartData* data = new ThreadStartData(function, parameter);
|
||||
|
||||
pthread_t tid;
|
||||
result = pthread_create(&tid,
|
||||
&attr,
|
||||
ThreadStart,
|
||||
data);
|
||||
VALIDATE_PTHREAD_RESULT(result);
|
||||
|
||||
data_.tid_ = tid;
|
||||
result = pthread_create(&tid, &attr, ThreadStart, data);
|
||||
RETURN_ON_PTHREAD_FAILURE(result);
|
||||
|
||||
result = pthread_attr_destroy(&attr);
|
||||
VALIDATE_PTHREAD_RESULT(result);
|
||||
}
|
||||
RETURN_ON_PTHREAD_FAILURE(result);
|
||||
|
||||
|
||||
Thread::~Thread() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -16,22 +16,6 @@
|
||||
|
||||
namespace dart {
|
||||
|
||||
class ThreadData {
|
||||
private:
|
||||
ThreadData() {}
|
||||
~ThreadData() {}
|
||||
|
||||
pthread_t* tid() { return &tid_; }
|
||||
|
||||
pthread_t tid_;
|
||||
|
||||
friend class Thread;
|
||||
|
||||
DISALLOW_ALLOCATION();
|
||||
DISALLOW_COPY_AND_ASSIGN(ThreadData);
|
||||
};
|
||||
|
||||
|
||||
class MutexData {
|
||||
private:
|
||||
MutexData() {}
|
||||
|
||||
@@ -10,27 +10,37 @@
|
||||
|
||||
namespace dart {
|
||||
|
||||
#define VALIDATE_PTHREAD_RESULT(result) \
|
||||
#define VALIDATE_PTHREAD_RESULT(result) \
|
||||
if (result != 0) { \
|
||||
FATAL2("pthread error: %d (%s)", result, strerror(result)); \
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
#define RETURN_ON_PTHREAD_FAILURE(result) \
|
||||
if (result != 0) { \
|
||||
fprintf(stderr, "%s:%d: pthread error: %d (%s)\n", \
|
||||
__FILE__, __LINE__, result, strerror(result)); \
|
||||
return result; \
|
||||
}
|
||||
#else
|
||||
#define RETURN_ON_PTHREAD_FAILURE(result) \
|
||||
if (result != 0) return result;
|
||||
#endif
|
||||
|
||||
|
||||
class ThreadStartData {
|
||||
public:
|
||||
ThreadStartData(Thread::ThreadStartFunction function,
|
||||
uword parameter,
|
||||
Thread* thread)
|
||||
: function_(function), parameter_(parameter), thread_(thread) {}
|
||||
uword parameter)
|
||||
: function_(function), parameter_(parameter) {}
|
||||
|
||||
Thread::ThreadStartFunction function() const { return function_; }
|
||||
uword parameter() const { return parameter_; }
|
||||
Thread* thread() const { return thread_; }
|
||||
|
||||
private:
|
||||
Thread::ThreadStartFunction function_;
|
||||
uword parameter_;
|
||||
Thread* thread_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ThreadStartData);
|
||||
};
|
||||
@@ -44,47 +54,36 @@ static void* ThreadStart(void* data_ptr) {
|
||||
|
||||
Thread::ThreadStartFunction function = data->function();
|
||||
uword parameter = data->parameter();
|
||||
Thread* thread = data->thread();
|
||||
delete data;
|
||||
|
||||
// Call the supplied thread start function handing it its parameters.
|
||||
function(parameter);
|
||||
|
||||
// When the function returns here, make sure that the thread is deleted.
|
||||
delete thread;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Thread::Thread(ThreadStartFunction function, uword parameter) {
|
||||
int Thread::Start(ThreadStartFunction function, uword parameter) {
|
||||
pthread_attr_t attr;
|
||||
int result = pthread_attr_init(&attr);
|
||||
VALIDATE_PTHREAD_RESULT(result);
|
||||
RETURN_ON_PTHREAD_FAILURE(result);
|
||||
|
||||
result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
VALIDATE_PTHREAD_RESULT(result);
|
||||
RETURN_ON_PTHREAD_FAILURE(result);
|
||||
|
||||
result = pthread_attr_setstacksize(&attr, 128 * KB);
|
||||
VALIDATE_PTHREAD_RESULT(result);
|
||||
RETURN_ON_PTHREAD_FAILURE(result);
|
||||
|
||||
ThreadStartData* data = new ThreadStartData(function, parameter, this);
|
||||
ThreadStartData* data = new ThreadStartData(function, parameter);
|
||||
|
||||
pthread_t tid;
|
||||
result = pthread_create(&tid,
|
||||
&attr,
|
||||
ThreadStart,
|
||||
data);
|
||||
VALIDATE_PTHREAD_RESULT(result);
|
||||
|
||||
data_.tid_ = tid;
|
||||
result = pthread_create(&tid, &attr, ThreadStart, data);
|
||||
RETURN_ON_PTHREAD_FAILURE(result);
|
||||
|
||||
result = pthread_attr_destroy(&attr);
|
||||
VALIDATE_PTHREAD_RESULT(result);
|
||||
}
|
||||
RETURN_ON_PTHREAD_FAILURE(result);
|
||||
|
||||
|
||||
Thread::~Thread() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,22 +15,6 @@
|
||||
|
||||
namespace dart {
|
||||
|
||||
class ThreadData {
|
||||
private:
|
||||
ThreadData() {}
|
||||
~ThreadData() {}
|
||||
|
||||
pthread_t* tid() { return &tid_; }
|
||||
|
||||
pthread_t tid_;
|
||||
|
||||
friend class Thread;
|
||||
|
||||
DISALLOW_ALLOCATION();
|
||||
DISALLOW_COPY_AND_ASSIGN(ThreadData);
|
||||
};
|
||||
|
||||
|
||||
class MutexData {
|
||||
private:
|
||||
MutexData() {}
|
||||
|
||||
@@ -12,19 +12,15 @@ namespace dart {
|
||||
|
||||
class ThreadStartData {
|
||||
public:
|
||||
ThreadStartData(Thread::ThreadStartFunction function,
|
||||
uword parameter,
|
||||
Thread* thread)
|
||||
: function_(function), parameter_(parameter), thread_(thread) {}
|
||||
ThreadStartData(Thread::ThreadStartFunction function, uword parameter)
|
||||
: function_(function), parameter_(parameter) {}
|
||||
|
||||
Thread::ThreadStartFunction function() const { return function_; }
|
||||
uword parameter() const { return parameter_; }
|
||||
Thread* thread() const { return thread_; }
|
||||
|
||||
private:
|
||||
Thread::ThreadStartFunction function_;
|
||||
uword parameter_;
|
||||
Thread* thread_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ThreadStartData);
|
||||
};
|
||||
@@ -38,33 +34,31 @@ static unsigned int __stdcall ThreadEntry(void* data_ptr) {
|
||||
|
||||
Thread::ThreadStartFunction function = data->function();
|
||||
uword parameter = data->parameter();
|
||||
Thread* thread = data->thread();
|
||||
delete data;
|
||||
|
||||
// Call the supplied thread start function handing it its parameters.
|
||||
function(parameter);
|
||||
|
||||
// When the function returns here, make sure that the thread is deleted.
|
||||
delete thread;
|
||||
// When the function returns here close the handle.
|
||||
CloseHandle(GetCurrentThread());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Thread::Thread(ThreadStartFunction function, uword parameter) {
|
||||
ThreadStartData* start_data = new ThreadStartData(function, parameter, this);
|
||||
int Thread::Start(ThreadStartFunction function, uword parameter) {
|
||||
ThreadStartData* start_data = new ThreadStartData(function, parameter);
|
||||
uint32_t tid;
|
||||
data_.thread_handle_ =
|
||||
_beginthreadex(NULL, 64 * KB, ThreadEntry, start_data, 0, &tid);
|
||||
if (data_.thread_handle_ == -1) {
|
||||
FATAL("Thread creation failed");
|
||||
uintptr_t thread =
|
||||
_beginthreadex(NULL, 64 * KB, ThreadEntry, start_data, 0, &tid);
|
||||
if (thread == -1L || thread == 0) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "_beginthreadex error: %d (%s)\n", errno, strerror(errno));
|
||||
#endif
|
||||
return errno;
|
||||
}
|
||||
data_.tid_ = tid;
|
||||
}
|
||||
|
||||
|
||||
Thread::~Thread() {
|
||||
CloseHandle(reinterpret_cast<HANDLE>(data_.thread_handle_));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -13,21 +13,6 @@
|
||||
|
||||
namespace dart {
|
||||
|
||||
class ThreadData {
|
||||
private:
|
||||
ThreadData() {}
|
||||
~ThreadData() {}
|
||||
|
||||
uintptr_t thread_handle_;
|
||||
uint32_t tid_;
|
||||
|
||||
friend class Thread;
|
||||
|
||||
DISALLOW_ALLOCATION();
|
||||
DISALLOW_COPY_AND_ASSIGN(ThreadData);
|
||||
};
|
||||
|
||||
|
||||
class MutexData {
|
||||
private:
|
||||
MutexData() {}
|
||||
|
||||
@@ -3116,8 +3116,8 @@ TEST_CASE(IsolateInterrupt) {
|
||||
Isolate::SetInterruptCallback(IsolateInterruptTestCallback);
|
||||
|
||||
sync = new Monitor();
|
||||
Thread* thread = new Thread(BusyLoop_start, 0);
|
||||
EXPECT(thread != NULL);
|
||||
int result = Thread::Start(BusyLoop_start, 0);
|
||||
EXPECT_EQ(0, result);
|
||||
|
||||
{
|
||||
MonitorLocker ml(sync);
|
||||
|
||||
@@ -155,8 +155,8 @@ void MessageReceiver_start(uword unused) {
|
||||
TEST_CASE(MessageQueue_WaitNotify) {
|
||||
sync = new Monitor();
|
||||
|
||||
Thread* thread = new Thread(MessageReceiver_start, 0);
|
||||
EXPECT(thread != NULL);
|
||||
int result = Thread::Start(MessageReceiver_start, 0);
|
||||
EXPECT_EQ(0, result);
|
||||
|
||||
// Wait for the shared queue to be created.
|
||||
while (shared_queue == NULL) {
|
||||
|
||||
@@ -60,7 +60,10 @@ static void RunWorker(uword parameter) {
|
||||
|
||||
|
||||
void NativeMessageHandler::StartWorker() {
|
||||
new Thread(RunWorker, reinterpret_cast<uword>(this));
|
||||
int result = Thread::Start(RunWorker, reinterpret_cast<uword>(this));
|
||||
if (result != 0) {
|
||||
FATAL1("Failed to start native message handler worker thread %d", result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -193,8 +193,8 @@ void ThreadedPort_start(uword parameter) {
|
||||
TEST_CASE(ThreadedPort) {
|
||||
intptr_t local = PortMap::CreatePort(Isolate::Current()->message_handler());
|
||||
|
||||
Thread* thr = new Thread(ThreadedPort_start, local);
|
||||
EXPECT(thr != NULL);
|
||||
int result = Thread::Start(ThreadedPort_start, local);
|
||||
EXPECT_EQ(0, result);
|
||||
|
||||
Message* msg = NextMessage();
|
||||
EXPECT_EQ(local, msg->dest_port());
|
||||
|
||||
Reference in New Issue
Block a user