diff options
author | deanm@google.com <deanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-03 16:47:37 +0000 |
---|---|---|
committer | deanm@google.com <deanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-03 16:47:37 +0000 |
commit | 83a05ddf63cc5920ad04b0a6936fb8f5625daa07 (patch) | |
tree | 117361a500928d197eb8e919e8356906e6276c43 /base/thread_local_unittest.cc | |
parent | acc0d96fda8b5389f30bf47ca297ca8755f9778c (diff) | |
download | chromium_src-83a05ddf63cc5920ad04b0a6936fb8f5625daa07.zip chromium_src-83a05ddf63cc5920ad04b0a6936fb8f5625daa07.tar.gz chromium_src-83a05ddf63cc5920ad04b0a6936fb8f5625daa07.tar.bz2 |
Add ThreadLocalPointer and ThreadLocalBoolean abstractions, that will deprecate the old ThreadLocalStorage / TLSSlot APIs.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1678 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/thread_local_unittest.cc')
-rw-r--r-- | base/thread_local_unittest.cc | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/base/thread_local_unittest.cc b/base/thread_local_unittest.cc new file mode 100644 index 0000000..9d6f875 --- /dev/null +++ b/base/thread_local_unittest.cc @@ -0,0 +1,159 @@ +// Copyright (c) 2006-2008 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 "base/logging.h" +#include "base/simple_thread.h" +#include "base/thread_local.h" +#include "base/waitable_event.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class ThreadLocalTesterBase : public base::DelegateSimpleThreadPool::Delegate { + public: + typedef base::ThreadLocalPointer<ThreadLocalTesterBase> TLPType; + + ThreadLocalTesterBase(TLPType* tlp, base::WaitableEvent* done) + : tlp_(tlp), done_(done) { } + ~ThreadLocalTesterBase() { } + + protected: + TLPType* tlp_; + base::WaitableEvent* done_; +}; + +class SetThreadLocal : public ThreadLocalTesterBase { + public: + SetThreadLocal(TLPType* tlp, base::WaitableEvent* done) + : ThreadLocalTesterBase(tlp, done), val_(NULL) { } + ~SetThreadLocal() { } + + void set_value(ThreadLocalTesterBase* val) { val_ = val; } + + virtual void Run() { + DCHECK(!done_->IsSignaled()); + tlp_->Set(val_); + done_->Signal(); + } + + private: + ThreadLocalTesterBase* val_; +}; + +class GetThreadLocal : public ThreadLocalTesterBase { + public: + GetThreadLocal(TLPType* tlp, base::WaitableEvent* done) + : ThreadLocalTesterBase(tlp, done), ptr_(NULL) { } + ~GetThreadLocal() { } + + void set_ptr(ThreadLocalTesterBase** ptr) { ptr_ = ptr; } + + virtual void Run() { + DCHECK(!done_->IsSignaled()); + *ptr_ = tlp_->Get(); + done_->Signal(); + } + + private: + ThreadLocalTesterBase** ptr_; +}; + +} // namespace + +// In this test, we start 2 threads which will access a ThreadLocalPointer. We +// make sure the default is NULL, and the pointers are unique to the threads. +TEST(ThreadLocalTest, Pointer) { + base::DelegateSimpleThreadPool tp1("ThreadLocalTest tp1", 1); + base::DelegateSimpleThreadPool tp2("ThreadLocalTest tp1", 1); + tp1.Start(); + tp2.Start(); + + base::ThreadLocalPointer<ThreadLocalTesterBase> tlp; + + static ThreadLocalTesterBase* const kBogusPointer = + reinterpret_cast<ThreadLocalTesterBase*>(0x1234); + + ThreadLocalTesterBase* tls_val; + base::WaitableEvent done(true, false); + + GetThreadLocal getter(&tlp, &done); + getter.set_ptr(&tls_val); + + // Check that both threads defaulted to NULL. + tls_val = kBogusPointer; + done.Reset(); + tp1.AddWork(&getter); + done.Wait(); + EXPECT_EQ(NULL, tls_val); + + tls_val = kBogusPointer; + done.Reset(); + tp2.AddWork(&getter); + done.Wait(); + EXPECT_EQ(NULL, tls_val); + + + SetThreadLocal setter(&tlp, &done); + setter.set_value(kBogusPointer); + + // Have thread 1 set their pointer value to kBogusPointer. + done.Reset(); + tp1.AddWork(&setter); + done.Wait(); + + tls_val = NULL; + done.Reset(); + tp1.AddWork(&getter); + done.Wait(); + EXPECT_EQ(kBogusPointer, tls_val); + + // Make sure thread 2 is still NULL + tls_val = kBogusPointer; + done.Reset(); + tp2.AddWork(&getter); + done.Wait(); + EXPECT_EQ(NULL, tls_val); + + // Set thread 2 to kBogusPointer + 1. + setter.set_value(kBogusPointer + 1); + + done.Reset(); + tp2.AddWork(&setter); + done.Wait(); + + tls_val = NULL; + done.Reset(); + tp2.AddWork(&getter); + done.Wait(); + EXPECT_EQ(kBogusPointer + 1, tls_val); + + // Make sure thread 1 is still kBogusPointer. + tls_val = NULL; + done.Reset(); + tp1.AddWork(&getter); + done.Wait(); + EXPECT_EQ(kBogusPointer, tls_val); + + tp1.JoinAll(); + tp2.JoinAll(); +} + +TEST(ThreadLocalTest, Boolean) { + { + base::ThreadLocalBoolean tlb; + EXPECT_EQ(false, tlb.Get()); + + tlb.Set(false); + EXPECT_EQ(false, tlb.Get()); + + tlb.Set(true); + EXPECT_EQ(true, tlb.Get()); + } + + // Our slot should have been freed, we're all reset. + { + base::ThreadLocalBoolean tlb; + EXPECT_EQ(false, tlb.Get()); + } +} |