summaryrefslogtreecommitdiffstats
path: root/base/thread_local_unittest.cc
diff options
context:
space:
mode:
authordeanm@google.com <deanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-09-03 16:47:37 +0000
committerdeanm@google.com <deanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-09-03 16:47:37 +0000
commit83a05ddf63cc5920ad04b0a6936fb8f5625daa07 (patch)
tree117361a500928d197eb8e919e8356906e6276c43 /base/thread_local_unittest.cc
parentacc0d96fda8b5389f30bf47ca297ca8755f9778c (diff)
downloadchromium_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.cc159
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());
+ }
+}