license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 1 | // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 4 | |
[email protected] | fe236c9 | 2008-09-11 23:37:54 | [diff] [blame] | 5 | #if defined(OS_WIN) |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 6 | #include <windows.h> |
| 7 | #include <process.h> |
[email protected] | fe236c9 | 2008-09-11 23:37:54 | [diff] [blame] | 8 | #endif |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 9 | |
[email protected] | fe236c9 | 2008-09-11 23:37:54 | [diff] [blame] | 10 | #include "base/simple_thread.h" |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 11 | #include "base/thread_local_storage.h" |
| 12 | #include "testing/gtest/include/gtest/gtest.h" |
| 13 | |
[email protected] | fe236c9 | 2008-09-11 23:37:54 | [diff] [blame] | 14 | #if defined(OS_WIN) |
| 15 | // Ignore warnings about ptr->int conversions that we use when |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 16 | // storing ints into ThreadLocalStorage. |
| 17 | #pragma warning(disable : 4311 4312) |
[email protected] | fe236c9 | 2008-09-11 23:37:54 | [diff] [blame] | 18 | #endif |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 19 | |
[email protected] | fe236c9 | 2008-09-11 23:37:54 | [diff] [blame] | 20 | const int kInitialTlsValue = 0x5555; |
| 21 | static ThreadLocalStorage::Slot tls_slot(base::LINKER_INITIALIZED); |
| 22 | |
| 23 | |
| 24 | class ThreadLocalStorageRunner : public base::DelegateSimpleThread::Delegate { |
| 25 | public: |
| 26 | explicit ThreadLocalStorageRunner(int* tls_value_ptr) |
| 27 | : tls_value_ptr_(tls_value_ptr) {} |
| 28 | |
| 29 | virtual ~ThreadLocalStorageRunner() {} |
| 30 | |
| 31 | virtual void Run() { |
| 32 | *tls_value_ptr_ = kInitialTlsValue; |
| 33 | tls_slot.Set(tls_value_ptr_); |
| 34 | |
| 35 | int *ptr = static_cast<int*>(tls_slot.Get()); |
| 36 | EXPECT_EQ(ptr, tls_value_ptr_); |
| 37 | EXPECT_EQ(*ptr, kInitialTlsValue); |
| 38 | *tls_value_ptr_ = 0; |
| 39 | |
| 40 | ptr = static_cast<int*>(tls_slot.Get()); |
| 41 | EXPECT_EQ(ptr, tls_value_ptr_); |
| 42 | EXPECT_EQ(*ptr, 0); |
| 43 | } |
| 44 | |
| 45 | private: |
| 46 | int* tls_value_ptr_; |
| 47 | DISALLOW_COPY_AND_ASSIGN(ThreadLocalStorageRunner); |
| 48 | }; |
| 49 | |
| 50 | |
| 51 | void ThreadLocalStorageCleanup(void *value) { |
| 52 | int *ptr = reinterpret_cast<int*>(value); |
| 53 | if (ptr) |
| 54 | *ptr = kInitialTlsValue; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 55 | } |
| 56 | |
| 57 | |
| 58 | TEST(ThreadLocalStorageTest, Basics) { |
[email protected] | 6a6e657 | 2008-08-20 22:54:52 | [diff] [blame] | 59 | ThreadLocalStorage::Slot slot; |
| 60 | slot.Set(reinterpret_cast<void*>(123)); |
| 61 | int value = reinterpret_cast<int>(slot.Get()); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 62 | EXPECT_EQ(value, 123); |
| 63 | } |
| 64 | |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 65 | TEST(ThreadLocalStorageTest, TLSDestructors) { |
| 66 | // Create a TLS index with a destructor. Create a set of |
| 67 | // threads that set the TLS, while the destructor cleans it up. |
| 68 | // After the threads finish, verify that the value is cleaned up. |
| 69 | const int kNumThreads = 5; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 70 | int values[kNumThreads]; |
[email protected] | fe236c9 | 2008-09-11 23:37:54 | [diff] [blame] | 71 | ThreadLocalStorageRunner* thread_delegates[kNumThreads]; |
| 72 | base::DelegateSimpleThread* threads[kNumThreads]; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 73 | |
[email protected] | 6a6e657 | 2008-08-20 22:54:52 | [diff] [blame] | 74 | tls_slot.Initialize(ThreadLocalStorageCleanup); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 75 | |
| 76 | // Spawn the threads. |
[email protected] | fe236c9 | 2008-09-11 23:37:54 | [diff] [blame] | 77 | for (int index = 0; index < kNumThreads; index++) { |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 78 | values[index] = kInitialTlsValue; |
[email protected] | fe236c9 | 2008-09-11 23:37:54 | [diff] [blame] | 79 | thread_delegates[index] = new ThreadLocalStorageRunner(&values[index]); |
| 80 | threads[index] = new base::DelegateSimpleThread(thread_delegates[index], |
| 81 | "tls thread"); |
| 82 | threads[index]->Start(); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 83 | } |
| 84 | |
| 85 | // Wait for the threads to finish. |
| 86 | for (int index = 0; index < kNumThreads; index++) { |
[email protected] | fe236c9 | 2008-09-11 23:37:54 | [diff] [blame] | 87 | threads[index]->Join(); |
| 88 | delete threads[index]; |
| 89 | delete thread_delegates[index]; |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 90 | |
[email protected] | fe236c9 | 2008-09-11 23:37:54 | [diff] [blame] | 91 | // Verify that the destructor was called and that we reset. |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 92 | EXPECT_EQ(values[index], kInitialTlsValue); |
| 93 | } |
| 94 | } |