summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-07 20:12:28 +0000
committeravi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-07 20:12:28 +0000
commite82b706db2d3da13746b66fd5ab7d5dd38fab17e (patch)
tree481f0dc57f23c984b5a5b0a9c169b6e928b9258f
parentf3adb5c4f36fd3233d0c0baad5eaef76da462a87 (diff)
downloadchromium_src-e82b706db2d3da13746b66fd5ab7d5dd38fab17e.zip
chromium_src-e82b706db2d3da13746b66fd5ab7d5dd38fab17e.tar.gz
chromium_src-e82b706db2d3da13746b66fd5ab7d5dd38fab17e.tar.bz2
Port in threading for Posix. Will require fixes to MessageLoop and Task to compile on the Mac, though.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@532 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/thread.cc2
-rw-r--r--base/thread.h19
-rw-r--r--base/thread_local_storage.h7
-rw-r--r--base/thread_local_storage_posix.cc53
-rw-r--r--base/thread_posix.cc102
5 files changed, 174 insertions, 9 deletions
diff --git a/base/thread.cc b/base/thread.cc
index 25379e1..0a19a16 100644
--- a/base/thread.cc
+++ b/base/thread.cc
@@ -126,7 +126,7 @@ typedef struct tagTHREADNAME_INFO {
// On XP, you can only get the ThreadId of the current
// thread. So it is expected that you'll call this after the
// thread starts up; hence, it is static.
-void Thread::SetThreadName(const char* name, DWORD tid) {
+void Thread::SetThreadName(const char* name, unsigned int tid) {
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = name;
diff --git a/base/thread.h b/base/thread.h
index 7ed2402..1780d85 100644
--- a/base/thread.h
+++ b/base/thread.h
@@ -30,7 +30,6 @@
#ifndef BASE_THREAD_H__
#define BASE_THREAD_H__
-#include <wtypes.h>
#include <string>
#include "base/basictypes.h"
@@ -38,6 +37,14 @@
class MessageLoop;
+// Types that differ
+#if defined(OS_WIN)
+#include <wtypes.h>
+typedef unsigned int ThreadId;
+#elif defined(OS_POSIX)
+typedef pthread_t ThreadId;
+#endif
+
// A simple thread abstraction that establishes a MessageLoop on a new thread.
// The consumer uses the MessageLoop of the thread to cause code to execute on
// the thread. When this object is destroyed the thread is terminated. All
@@ -90,7 +97,7 @@ class Thread {
void NonBlockingStop();
// Returns the message loop for this thread. Use the MessageLoop's
- // Posttask methods to execute code on the thread. This only returns
+ // PostTask methods to execute code on the thread. This only returns
// non-null after a successful call to Start. After Stop has been called,
// this will return NULL.
//
@@ -108,7 +115,7 @@ class Thread {
// Sets the thread name if a debugger is currently attached. Has no effect
// otherwise. To set the name of the current thread, pass GetCurrentThreadId()
// as the tid parameter.
- static void SetThreadName(const char* name, DWORD tid);
+ static void SetThreadName(const char* name, ThreadId tid);
protected:
// Called just prior to starting the message loop
@@ -121,10 +128,12 @@ class Thread {
void InternalStop(bool run_message_loop);
private:
+#ifdef OS_WIN
static unsigned __stdcall ThreadFunc(void* param);
-
HANDLE thread_;
- unsigned thread_id_;
+#endif
+
+ ThreadId thread_id_;
MessageLoop* message_loop_;
std::string name_;
static TLSSlot tls_index_;
diff --git a/base/thread_local_storage.h b/base/thread_local_storage.h
index 51536f3..245a73f 100644
--- a/base/thread_local_storage.h
+++ b/base/thread_local_storage.h
@@ -27,14 +27,15 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#ifndef BASE_THREAD_LOCAL_STORAGE_H__
-#define BASE_THREAD_LOCAL_STORAGE_H__
+#ifndef BASE_THREAD_LOCAL_STORAGE_H_
+#define BASE_THREAD_LOCAL_STORAGE_H_
#include "base/basictypes.h"
#if defined(OS_WIN)
typedef int TLSSlot;
#elif defined(OS_POSIX)
+#include <pthread.h>
typedef pthread_key_t TLSSlot;
#endif // OS_*
@@ -92,4 +93,4 @@ class ThreadLocalStorage {
DISALLOW_EVIL_CONSTRUCTORS(ThreadLocalStorage);
};
-#endif // BASE_THREAD_LOCAL_STORAGE_H__
+#endif // BASE_THREAD_LOCAL_STORAGE_H_
diff --git a/base/thread_local_storage_posix.cc b/base/thread_local_storage_posix.cc
new file mode 100644
index 0000000..bcc982f
--- /dev/null
+++ b/base/thread_local_storage_posix.cc
@@ -0,0 +1,53 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "base/thread_local_storage.h"
+
+#include "base/logging.h"
+
+TLSSlot ThreadLocalStorage::Alloc(TLSDestructorFunc destructor) {
+ TLSSlot key;
+ int error = pthread_key_create(&key, destructor);
+ if (error)
+ NOTREACHED();
+
+ return key;
+}
+
+void ThreadLocalStorage::Free(TLSSlot slot) {
+ pthread_key_delete(slot);
+}
+
+void* ThreadLocalStorage::Get(TLSSlot slot) {
+ return pthread_getspecific(slot);
+}
+
+void ThreadLocalStorage::Set(TLSSlot slot, void* value) {
+ pthread_setspecific(slot, value);
+}
diff --git a/base/thread_posix.cc b/base/thread_posix.cc
new file mode 100644
index 0000000..e04ebcb
--- /dev/null
+++ b/base/thread_posix.cc
@@ -0,0 +1,102 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "base/thread.h"
+
+#include "base/message_loop.h"
+#include "base/ref_counted.h"
+#include "base/string_util.h"
+
+// This task is used to trigger the message loop to exit.
+class ThreadQuitTask : public Task {
+ public:
+ virtual void Run() {
+ MessageLoop::current()->Quit();
+#ifndef NDEBUG
+ Thread::SetThreadWasQuitProperly(true);
+#endif
+ }
+};
+
+Thread::Thread(const char *name)
+ : thread_id_(0),
+ message_loop_(NULL),
+ name_(name) {
+ DCHECK(tls_index_) << "static initializer failed";
+}
+
+Thread::~Thread() {
+ Stop();
+}
+
+void* ThreadFunc(void* closure) {
+ // TODO(pinkerton): I have no clue what to do here
+
+ pthread_exit(NULL);
+}
+
+// We use this thread-local variable to record whether or not a thread exited
+// because its Stop method was called. This allows us to catch cases where
+// MessageLoop::Quit() is called directly, which is unexpected when using a
+// Thread to setup and run a MessageLoop.
+// Note that if we start doing complex stuff in other static initializers
+// this could cause problems.
+TLSSlot Thread::tls_index_ = ThreadLocalStorage::Alloc();
+
+void Thread::SetThreadWasQuitProperly(bool flag) {
+ ThreadLocalStorage::Set(tls_index_, reinterpret_cast<void*>(flag));
+}
+
+bool Thread::GetThreadWasQuitProperly() {
+ return (ThreadLocalStorage::Get(tls_index_) != 0);
+}
+
+
+bool Thread::Start() {
+ bool success = false;
+ int result = pthread_create(&thread_id_, NULL, ThreadFunc, &message_loop_);
+ if (!result)
+ success = true;
+
+ return success;
+}
+
+void Thread::Stop() {
+// DCHECK_NE(thread_id_, GetCurrentThreadId())
+// << "Can't call Stop() on itself";
+
+ // We had better have a message loop at this point! If we do not, then it
+ // most likely means that the thread terminated unexpectedly, probably due
+ // to someone calling Quit() on our message loop directly.
+ DCHECK(message_loop_);
+
+ message_loop_->PostTask(FROM_HERE, new ThreadQuitTask());
+
+ message_loop_ = NULL;
+}