diff options
author | avi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-07 20:12:28 +0000 |
---|---|---|
committer | avi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-07 20:12:28 +0000 |
commit | e82b706db2d3da13746b66fd5ab7d5dd38fab17e (patch) | |
tree | 481f0dc57f23c984b5a5b0a9c169b6e928b9258f /base | |
parent | f3adb5c4f36fd3233d0c0baad5eaef76da462a87 (diff) | |
download | chromium_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
Diffstat (limited to 'base')
-rw-r--r-- | base/thread.cc | 2 | ||||
-rw-r--r-- | base/thread.h | 19 | ||||
-rw-r--r-- | base/thread_local_storage.h | 7 | ||||
-rw-r--r-- | base/thread_local_storage_posix.cc | 53 | ||||
-rw-r--r-- | base/thread_posix.cc | 102 |
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; +} |