diff options
author | timurrrr@chromium.org <timurrrr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-03 21:11:34 +0000 |
---|---|---|
committer | timurrrr@chromium.org <timurrrr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-03 21:11:34 +0000 |
commit | baeb22f54fafa2b8394a7ccd74536ed7ccc23c34 (patch) | |
tree | b5bfb16f735a2fe506b9aecf7dd0b8dead9c7dc8 | |
parent | 36f5c5604d898b06763e0104980300c788e4ea48 (diff) | |
download | chromium_src-baeb22f54fafa2b8394a7ccd74536ed7ccc23c34.zip chromium_src-baeb22f54fafa2b8394a7ccd74536ed7ccc23c34.tar.gz chromium_src-baeb22f54fafa2b8394a7ccd74536ed7ccc23c34.tar.bz2 |
Rename AtomicFlag to CancelFlag, change its semantics a bit
Review URL: http://codereview.chromium.org/454025
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@33723 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/atomic_flag.cc | 28 | ||||
-rw-r--r-- | base/atomic_flag.h | 37 | ||||
-rw-r--r-- | base/atomic_flag_unittest.cc | 79 | ||||
-rw-r--r-- | base/base.gyp | 6 | ||||
-rw-r--r-- | base/cancellation_flag.cc | 22 | ||||
-rw-r--r-- | base/cancellation_flag.h | 42 | ||||
-rw-r--r-- | base/cancellation_flag_unittest.cc | 74 |
7 files changed, 141 insertions, 147 deletions
diff --git a/base/atomic_flag.cc b/base/atomic_flag.cc deleted file mode 100644 index 3e02543..0000000 --- a/base/atomic_flag.cc +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2009 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/atomic_flag.h" - -#include "base/dynamic_annotations.h" -#include "base/logging.h" - -namespace base { - -void AtomicFlag::Set() { - DCHECK(!flag_); - // Set() method can't be called if the flag has already been set. - - ANNOTATE_HAPPENS_BEFORE(&flag_); - base::subtle::Release_Store(&flag_, 1); -} - -bool AtomicFlag::IsSet() const { - bool ret = base::subtle::Acquire_Load(&flag_) != 0; - if (ret) { - ANNOTATE_HAPPENS_AFTER(&flag_); - } - return ret; -} - -} // namespace base diff --git a/base/atomic_flag.h b/base/atomic_flag.h deleted file mode 100644 index ee33bf2..0000000 --- a/base/atomic_flag.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2009 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. - -#ifndef BASE_ATOMIC_FLAG_H_ -#define BASE_ATOMIC_FLAG_H_ - -#include "base/atomicops.h" - -namespace base { - -// AtomicFlag allows threads to notify each other for a single occurrence -// of a single event. It maintains an abstract boolean "flag" that transitions -// to true at most once. It provides calls to query the boolean. -// -// Memory ordering: For any threads X and Y, if X calls Set(), then any -// action taken by X before it calls Set() is visible to thread Y after -// Y receives a true return value from IsSet(). -class AtomicFlag { - public: - // Sets "flag_" to "initial_value". - explicit AtomicFlag(bool initial_value = false) - : flag_(initial_value ? 1 : 0) { } - ~AtomicFlag() {} - - void Set(); // Set "flag_" to true. May be called only once. - bool IsSet() const; // Return "flag_". - - private: - base::subtle::Atomic32 flag_; - - DISALLOW_COPY_AND_ASSIGN(AtomicFlag); -}; - -} // namespace base - -#endif // BASE_ATOMIC_FLAG_H_ diff --git a/base/atomic_flag_unittest.cc b/base/atomic_flag_unittest.cc deleted file mode 100644 index 6f53b4b..0000000 --- a/base/atomic_flag_unittest.cc +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2009 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. - -// Tests of AtomicFlag class. - -#include "base/atomic_flag.h" -#include "base/logging.h" -#include "base/spin_wait.h" -#include "base/time.h" -#include "base/thread.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -using base::AtomicFlag; -using base::TimeDelta; -using base::Thread; - -namespace { - -//------------------------------------------------------------------------------ -// Define our test class. -//------------------------------------------------------------------------------ - -class NotifyTask : public Task { - public: - explicit NotifyTask(AtomicFlag* flag) : flag_(flag) { - } - virtual void Run() { - flag_->Set(); - } - private: - AtomicFlag* flag_; -}; - -TEST(AtomicFlagTest, SimpleSingleThreadedTest) { - AtomicFlag flag; - CHECK(!flag.IsSet()); - flag.Set(); - CHECK(flag.IsSet()); -} - -TEST(AtomicFlagTest, SimpleSingleThreadedTestPrenotified) { - AtomicFlag flag(true); - CHECK(flag.IsSet()); -} - -#if defined(OS_WIN) -#define DISABLED_ON_WIN(x) DISABLED_##x -#else -#define DISABLED_ON_WIN(x) x -#endif - -// AtomicFlag should die on a DCHECK if Set() is called more than once. -// This test isn't Windows-friendly yet since ASSERT_DEATH doesn't catch tests -// failed on DCHECK. See http://crbug.com/24885 for the details. -TEST(AtomicFlagTest, DISABLED_ON_WIN(DoubleSetDeathTest)) { - // Checks that Set() can't be called more than once. - ::testing::FLAGS_gtest_death_test_style = "threadsafe"; - AtomicFlag flag; - flag.Set(); - ASSERT_DEBUG_DEATH(flag.Set(), ""); -} - -TEST(AtomicFlagTest, SimpleThreadedTest) { - Thread t("AtomicFlagTest.SimpleThreadedTest"); - EXPECT_TRUE(t.Start()); - EXPECT_TRUE(t.message_loop()); - EXPECT_TRUE(t.IsRunning()); - - AtomicFlag flag; - CHECK(!flag.IsSet()); - t.message_loop()->PostTask(FROM_HERE, new NotifyTask(&flag)); - SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(TimeDelta::FromSeconds(10), - flag.IsSet()); - CHECK(flag.IsSet()); -} - -} // namespace diff --git a/base/base.gyp b/base/base.gyp index 0a7aaba..9e8e60e 100644 --- a/base/base.gyp +++ b/base/base.gyp @@ -68,8 +68,6 @@ 'atomicops_internals_x86_gcc.cc', 'at_exit.cc', 'at_exit.h', - 'atomic_flag.h', - 'atomic_flag.cc', 'atomic_ref_count.h', 'atomic_sequence_num.h', 'atomicops.h', @@ -93,6 +91,8 @@ 'basictypes.h', 'bits.h', 'bzip2_error_handler.cc', + 'cancellation_flag.h', + 'cancellation_flag.cc', 'chrome_application_mac.h', 'chrome_application_mac.mm', 'cocoa_protocols_mac.h', @@ -589,10 +589,10 @@ # Tests. 'at_exit_unittest.cc', - 'atomic_flag_unittest.cc', 'atomicops_unittest.cc', 'base64_unittest.cc', 'bits_unittest.cc', + 'cancellation_flag_unittest.cc', 'command_line_unittest.cc', 'condition_variable_unittest.cc', 'crypto/rsa_private_key_unittest.cc', diff --git a/base/cancellation_flag.cc b/base/cancellation_flag.cc new file mode 100644 index 0000000..75b6025 --- /dev/null +++ b/base/cancellation_flag.cc @@ -0,0 +1,22 @@ +// Copyright (c) 2009 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/cancellation_flag.h" + +#include "base/logging.h" + +namespace base { + +void CancellationFlag::Set() { +#if !defined(NDEBUG) + DCHECK(set_on_ == PlatformThread::CurrentId()); +#endif + base::subtle::Release_Store(&flag_, 1); +} + +bool CancellationFlag::IsSet() const { + return base::subtle::Acquire_Load(&flag_) != 0; +} + +} // namespace base diff --git a/base/cancellation_flag.h b/base/cancellation_flag.h new file mode 100644 index 0000000..b9c045d --- /dev/null +++ b/base/cancellation_flag.h @@ -0,0 +1,42 @@ +// Copyright (c) 2009 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. + +#ifndef BASE_CANCELLATION_FLAG_H_ +#define BASE_CANCELLATION_FLAG_H_ + +#include "base/atomicops.h" +#include "base/platform_thread.h" + +namespace base { + +// CancellationFlag allows one thread to cancel jobs executed on some worker +// thread. Calling Set() from one thread and IsSet() from a number of threads +// is thread-safe. +// +// This class IS NOT intended for synchronization between threads. +class CancellationFlag { + public: + CancellationFlag() : flag_(false) { +#if !defined(NDEBUG) + set_on_ = PlatformThread::CurrentId(); +#endif + } + ~CancellationFlag() {} + + // Set the flag. May only be called on the thread which owns the object. + void Set(); + bool IsSet() const; // Returns true iff the flag was set. + + private: + base::subtle::Atomic32 flag_; +#if !defined(NDEBUG) + PlatformThreadId set_on_; +#endif + + DISALLOW_COPY_AND_ASSIGN(CancellationFlag); +}; + +} // namespace base + +#endif // BASE_CANCELLATION_FLAG_H_ diff --git a/base/cancellation_flag_unittest.cc b/base/cancellation_flag_unittest.cc new file mode 100644 index 0000000..ffc8cf0 --- /dev/null +++ b/base/cancellation_flag_unittest.cc @@ -0,0 +1,74 @@ +// Copyright (c) 2009 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. + +// Tests of CancellationFlag class. + +#include "base/cancellation_flag.h" + +#include "base/logging.h" +#include "base/spin_wait.h" +#include "base/time.h" +#include "base/thread.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/platform_test.h" + +using base::CancellationFlag; +using base::TimeDelta; +using base::Thread; + +namespace { + +//------------------------------------------------------------------------------ +// Define our test class. +//------------------------------------------------------------------------------ + +class CancelTask : public Task { + public: + explicit CancelTask(CancellationFlag* flag) : flag_(flag) {} + virtual void Run() { + ASSERT_DEBUG_DEATH(flag_->Set(), ""); + } + private: + CancellationFlag* flag_; +}; + +TEST(CancellationFlagTest, SimpleSingleThreadedTest) { + CancellationFlag flag; + ASSERT_FALSE(flag.IsSet()); + flag.Set(); + ASSERT_TRUE(flag.IsSet()); +} + +TEST(CancellationFlagTest, DoubleSetTest) { + CancellationFlag flag; + ASSERT_FALSE(flag.IsSet()); + flag.Set(); + ASSERT_TRUE(flag.IsSet()); + flag.Set(); + ASSERT_TRUE(flag.IsSet()); +} + +#if defined(OS_WIN) +#define DISABLED_ON_WIN(x) DISABLED_##x +#else +#define DISABLED_ON_WIN(x) x +#endif + +// CancellationFlag should die on a DCHECK if Set() is called from +// other thread. +// This test isn't Windows-friendly yet since ASSERT_DEATH doesn't catch tests +// failed on DCHECK. See http://crbug.com/24885 for the details. +TEST(CancellationFlagTest, DISABLED_ON_WIN(SetOnDifferentThreadDeathTest)) { + // Checks that Set() can't be called from any other thread. + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + Thread t("CancellationFlagTest.SetOnDifferentThreadDeathTest"); + ASSERT_TRUE(t.Start()); + ASSERT_TRUE(t.message_loop()); + ASSERT_TRUE(t.IsRunning()); + + CancellationFlag flag; + t.message_loop()->PostTask(FROM_HERE, new CancelTask(&flag)); +} + +} // namespace |