summaryrefslogtreecommitdiffstats
path: root/base/threading/thread_local_unittest.cc
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-30 22:18:56 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-30 22:18:56 +0000
commit1357c32474af4190d22ccca26bf414443252784b (patch)
tree620927f5a079c5850e59d9774f4747b76d60ed11 /base/threading/thread_local_unittest.cc
parentb99603ceb9cbec4a3b1ca9ac535f6b1cbc951bb8 (diff)
downloadchromium_src-1357c32474af4190d22ccca26bf414443252784b.zip
chromium_src-1357c32474af4190d22ccca26bf414443252784b.tar.gz
chromium_src-1357c32474af4190d22ccca26bf414443252784b.tar.bz2
Move thread local stuff from base to base/threading and consistently use the
base namespace. This also fixes references to TLSSlot to base::ThreadLocalStorage::Slot. TEST=it compiles BUG=none Review URL: http://codereview.chromium.org/5986012 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70322 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/threading/thread_local_unittest.cc')
-rw-r--r--base/threading/thread_local_unittest.cc163
1 files changed, 163 insertions, 0 deletions
diff --git a/base/threading/thread_local_unittest.cc b/base/threading/thread_local_unittest.cc
new file mode 100644
index 0000000..f6bdd78
--- /dev/null
+++ b/base/threading/thread_local_unittest.cc
@@ -0,0 +1,163 @@
+// Copyright (c) 2010 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/threading/simple_thread.h"
+#include "base/threading/thread_local.h"
+#include "base/waitable_event.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+
+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(static_cast<ThreadLocalTesterBase*>(NULL), tls_val);
+
+ tls_val = kBogusPointer;
+ done.Reset();
+ tp2.AddWork(&getter);
+ done.Wait();
+ EXPECT_EQ(static_cast<ThreadLocalTesterBase*>(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(static_cast<ThreadLocalTesterBase*>(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_FALSE(tlb.Get());
+
+ tlb.Set(false);
+ EXPECT_FALSE(tlb.Get());
+
+ tlb.Set(true);
+ EXPECT_TRUE(tlb.Get());
+ }
+
+ // Our slot should have been freed, we're all reset.
+ {
+ base::ThreadLocalBoolean tlb;
+ EXPECT_FALSE(tlb.Get());
+ }
+}
+
+} // namespace base