| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/public/cpp/utility/mutex.h" | 5 #include "mojo/public/cpp/utility/mutex.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdlib.h> // For |rand()|. | 8 #include <stdlib.h> // For |rand()|. |
| 9 #include <time.h> // For |nanosleep()| (defined by POSIX). | 9 #include <time.h> // For |nanosleep()| (defined by POSIX). |
| 10 | 10 |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/compiler_specific.h" |
| 13 #include "mojo/public/cpp/system/macros.h" | 14 #include "mojo/public/cpp/system/macros.h" |
| 14 #include "mojo/public/cpp/utility/thread.h" | 15 #include "mojo/public/cpp/utility/thread.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 16 | 17 |
| 17 namespace mojo { | 18 namespace mojo { |
| 18 namespace { | 19 namespace { |
| 19 | 20 |
| 20 TEST(MutexTest, TrivialSingleThreaded) { | 21 TEST(MutexTest, TrivialSingleThreaded) { |
| 21 Mutex mutex; | 22 Mutex mutex; |
| 22 | 23 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 } | 86 } |
| 86 | 87 |
| 87 private: | 88 private: |
| 88 static void SleepALittle() { | 89 static void SleepALittle() { |
| 89 static const long kNanosPerMilli = 1000000; | 90 static const long kNanosPerMilli = 1000000; |
| 90 struct timespec req = { | 91 struct timespec req = { |
| 91 0, // Seconds. | 92 0, // Seconds. |
| 92 (rand() % 10) * kNanosPerMilli // Nanoseconds. | 93 (rand() % 10) * kNanosPerMilli // Nanoseconds. |
| 93 }; | 94 }; |
| 94 int rv = nanosleep(&req, nullptr); | 95 int rv = nanosleep(&req, nullptr); |
| 95 MOJO_ALLOW_UNUSED_LOCAL(rv); | 96 ALLOW_UNUSED_LOCAL(rv); |
| 96 assert(rv == 0); | 97 assert(rv == 0); |
| 97 } | 98 } |
| 98 | 99 |
| 99 const size_t times_to_lock_; | 100 const size_t times_to_lock_; |
| 100 const Type type_; | 101 const Type type_; |
| 101 const bool should_sleep_; | 102 const bool should_sleep_; |
| 102 Mutex* const mutex_; | 103 Mutex* const mutex_; |
| 103 int* const shared_value_; | 104 int* const shared_value_; |
| 104 | 105 |
| 105 MOJO_DISALLOW_COPY_AND_ASSIGN(Fiddler); | 106 DISALLOW_COPY_AND_ASSIGN(Fiddler); |
| 106 }; | 107 }; |
| 107 | 108 |
| 108 class FiddlerThread : public Thread { | 109 class FiddlerThread : public Thread { |
| 109 public: | 110 public: |
| 110 // Takes ownership of |fiddler|. | 111 // Takes ownership of |fiddler|. |
| 111 FiddlerThread(Fiddler* fiddler) | 112 FiddlerThread(Fiddler* fiddler) |
| 112 : fiddler_(fiddler) { | 113 : fiddler_(fiddler) { |
| 113 } | 114 } |
| 114 | 115 |
| 115 ~FiddlerThread() override { delete fiddler_; } | 116 ~FiddlerThread() override { delete fiddler_; } |
| 116 | 117 |
| 117 void Run() override { fiddler_->Fiddle(); } | 118 void Run() override { fiddler_->Fiddle(); } |
| 118 | 119 |
| 119 private: | 120 private: |
| 120 Fiddler* const fiddler_; | 121 Fiddler* const fiddler_; |
| 121 | 122 |
| 122 MOJO_DISALLOW_COPY_AND_ASSIGN(FiddlerThread); | 123 DISALLOW_COPY_AND_ASSIGN(FiddlerThread); |
| 123 }; | 124 }; |
| 124 | 125 |
| 125 // This does a stress test (that also checks exclusion). | 126 // This does a stress test (that also checks exclusion). |
| 126 TEST(MutexTest, ThreadedStress) { | 127 TEST(MutexTest, ThreadedStress) { |
| 127 static const size_t kNumThreads = 20; | 128 static const size_t kNumThreads = 20; |
| 128 static const int kTimesToLockEach = 20; | 129 static const int kTimesToLockEach = 20; |
| 129 assert(kNumThreads % 4 == 0); | 130 assert(kNumThreads % 4 == 0); |
| 130 | 131 |
| 131 Mutex mutex; | 132 Mutex mutex; |
| 132 int shared_value = 0; | 133 int shared_value = 0; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 if (try_lock_succeeded_) | 174 if (try_lock_succeeded_) |
| 174 mutex_->Unlock(); | 175 mutex_->Unlock(); |
| 175 } | 176 } |
| 176 | 177 |
| 177 bool try_lock_succeeded() const { return try_lock_succeeded_; } | 178 bool try_lock_succeeded() const { return try_lock_succeeded_; } |
| 178 | 179 |
| 179 private: | 180 private: |
| 180 Mutex* const mutex_; | 181 Mutex* const mutex_; |
| 181 bool try_lock_succeeded_; | 182 bool try_lock_succeeded_; |
| 182 | 183 |
| 183 MOJO_DISALLOW_COPY_AND_ASSIGN(TryThread); | 184 DISALLOW_COPY_AND_ASSIGN(TryThread); |
| 184 }; | 185 }; |
| 185 | 186 |
| 186 TEST(MutexTest, TryLock) { | 187 TEST(MutexTest, TryLock) { |
| 187 Mutex mutex; | 188 Mutex mutex; |
| 188 | 189 |
| 189 // |TryLock()| should succeed -- we don't have the lock. | 190 // |TryLock()| should succeed -- we don't have the lock. |
| 190 { | 191 { |
| 191 TryThread thread(&mutex); | 192 TryThread thread(&mutex); |
| 192 thread.Start(); | 193 thread.Start(); |
| 193 thread.Join(); | 194 thread.Join(); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 // Destroy lock with lock held. | 252 // Destroy lock with lock held. |
| 252 EXPECT_DEATH_IF_SUPPORTED({ | 253 EXPECT_DEATH_IF_SUPPORTED({ |
| 253 Mutex mutex; | 254 Mutex mutex; |
| 254 mutex.Lock(); | 255 mutex.Lock(); |
| 255 }, ""); | 256 }, ""); |
| 256 } | 257 } |
| 257 #endif // !defined(NDEBUG) | 258 #endif // !defined(NDEBUG) |
| 258 | 259 |
| 259 } // namespace | 260 } // namespace |
| 260 } // namespace mojo | 261 } // namespace mojo |
| OLD | NEW |