Commit 47ed7d6e authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

reset_once

Summary: Add `reset_once`, a mechanism to reset a `once_flag`.

Reviewed By: Mizuchi

Differential Revision: D27071246

fbshipit-source-id: 4824782fb0ce6380b72e3e657e6f5073029eaf14
parent ee776518
...@@ -103,6 +103,16 @@ FOLLY_ALWAYS_INLINE bool test_once(OnceFlag const& flag) noexcept { ...@@ -103,6 +103,16 @@ FOLLY_ALWAYS_INLINE bool test_once(OnceFlag const& flag) noexcept {
return flag.test_once(); return flag.test_once();
} }
// reset_once
//
// Resets a flag.
//
// Warning: unsafe to call concurrently with any other flag operations.
template <typename OnceFlag>
FOLLY_ALWAYS_INLINE void reset_once(OnceFlag& flag) noexcept {
return flag.reset_once();
}
template <typename Mutex, template <typename> class Atom> template <typename Mutex, template <typename> class Atom>
class basic_once_flag { class basic_once_flag {
public: public:
...@@ -117,6 +127,9 @@ class basic_once_flag { ...@@ -117,6 +127,9 @@ class basic_once_flag {
template <typename OnceFlag> template <typename OnceFlag>
friend bool test_once(OnceFlag const& flag) noexcept; friend bool test_once(OnceFlag const& flag) noexcept;
template <typename OnceFlag>
friend void reset_once(OnceFlag&) noexcept;
template <typename F, typename... Args> template <typename F, typename... Args>
FOLLY_NOINLINE void call_once_slow(F&& f, Args&&... args) { FOLLY_NOINLINE void call_once_slow(F&& f, Args&&... args) {
std::lock_guard<Mutex> lock(mutex_); std::lock_guard<Mutex> lock(mutex_);
...@@ -145,6 +158,10 @@ class basic_once_flag { ...@@ -145,6 +158,10 @@ class basic_once_flag {
return called_.load(std::memory_order_acquire); return called_.load(std::memory_order_acquire);
} }
FOLLY_ALWAYS_INLINE void reset_once() noexcept {
called_.store(false, std::memory_order_relaxed);
}
Atom<bool> called_{false}; Atom<bool> called_{false};
Mutex mutex_; Mutex mutex_;
}; };
...@@ -162,6 +179,9 @@ class compact_once_flag { ...@@ -162,6 +179,9 @@ class compact_once_flag {
template <typename OnceFlag> template <typename OnceFlag>
friend bool test_once(OnceFlag const& flag) noexcept; friend bool test_once(OnceFlag const& flag) noexcept;
template <typename OnceFlag>
friend void reset_once(OnceFlag&) noexcept;
template <typename F, typename... Args> template <typename F, typename... Args>
FOLLY_NOINLINE void call_once_slow(F&& f, Args&&... args) { FOLLY_NOINLINE void call_once_slow(F&& f, Args&&... args) {
folly::MicroLock::LockGuardWithData guard(mutex_); folly::MicroLock::LockGuardWithData guard(mutex_);
...@@ -191,6 +211,11 @@ class compact_once_flag { ...@@ -191,6 +211,11 @@ class compact_once_flag {
return mutex_.load(std::memory_order_acquire) != 0; return mutex_.load(std::memory_order_acquire) != 0;
} }
FOLLY_ALWAYS_INLINE void reset_once() noexcept {
folly::MicroLock::LockGuardWithData guard(mutex_);
guard.storeValue(0);
}
folly::MicroLock mutex_; folly::MicroLock mutex_;
}; };
......
...@@ -135,3 +135,12 @@ TYPED_TEST(FollyCallOnce, TryCallOnce) { ...@@ -135,3 +135,12 @@ TYPED_TEST(FollyCallOnce, TryCallOnce) {
EXPECT_TRUE(folly::try_call_once(once, []() noexcept { return true; })); EXPECT_TRUE(folly::try_call_once(once, []() noexcept { return true; }));
EXPECT_TRUE(folly::test_once(once)); EXPECT_TRUE(folly::test_once(once));
} }
TYPED_TEST(FollyCallOnce, ResetOnce) {
typename TestFixture::OnceFlag once;
EXPECT_FALSE(folly::test_once(once));
folly::call_once(once, [] {});
EXPECT_TRUE(folly::test_once(once));
folly::reset_once(once);
EXPECT_FALSE(folly::test_once(once));
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment