Skip to content

Commit 901ceae

Browse files
committed
[Threading] Add the ability to use any C++ callable in swift::once().
This allows the use of C++ lambdas and functors, in addition to plain old functions. rdar://90776105
1 parent 1c6618e commit 901ceae

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

include/swift/Threading/Once.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@ inline void once(once_t &predicate, void (*fn)(void *),
3131
threading_impl::once_impl(predicate, fn, context);
3232
}
3333

34+
/// Executes the given callable exactly once.
35+
/// The predicate argument must refer to a global or static variable of static
36+
/// extent of type swift::once_t.
37+
template <typename Callable>
38+
inline void once(once_t &predicate, const Callable &callable) {
39+
once(predicate, [](void *ctx) {
40+
const Callable &callable = *(const Callable*)(ctx);
41+
callable();
42+
}, (void *)(&callable));
43+
}
44+
3445
} // namespace swift
3546

3647
#endif // SWIFT_THREADING_ONCE_H

unittests/Threading/Once.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,18 @@ TEST(OnceTest, once_threaded) {
7171
ASSERT_EQ(1u, callCount);
7272
}
7373
}
74+
75+
// Check that swift::once works with a C++ lambda
76+
TEST(OnceTest, once_lambda) {
77+
static swift::once_t predicate;
78+
unsigned callCount = 0;
79+
80+
auto fn = [&callCount]() {
81+
++callCount;
82+
};
83+
84+
swift::once(predicate, fn);
85+
swift::once(predicate, fn);
86+
87+
ASSERT_EQ(1u, callCount);
88+
}

0 commit comments

Comments
 (0)