Skip to content

Commit c77faa0

Browse files
Tao Chen (RPC)facebook-github-bot
authored andcommitted
Resolve and save the type info of lambda creator
Differential Revision: D67317752 fbshipit-source-id: 6ac613fa7d291e2666c1a602ac55ca8c33071707
1 parent 30d997e commit c77faa0

File tree

5 files changed

+159
-29
lines changed

5 files changed

+159
-29
lines changed

third-party/folly/src/folly/observer/Observer-inl.h

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,59 @@
2121

2222
namespace folly {
2323
namespace observer_detail {
24+
template <typename F>
25+
observer::Observer<ResultOfUnwrapSharedPtr<F>> makeObserver(
26+
F&& creator,
27+
std::optional<Core::CreatorContext> creatorContext = std::nullopt) {
28+
if (!creatorContext) {
29+
creatorContext = Core::CreatorContext{&typeid(F)};
30+
}
31+
auto core = Core::create(
32+
[creator_2 = std::forward<F>(creator)]() mutable {
33+
return std::static_pointer_cast<const void>(creator_2());
34+
},
35+
std::move(creatorContext).value());
36+
37+
ObserverManager::initCore(core);
38+
39+
return observer::Observer<ResultOfUnwrapSharedPtr<F>>(core);
40+
}
41+
2442
template <typename F>
2543
observer::Observer<ResultOfNoObserverUnwrap<F>> makeObserver(F&& creator) {
26-
return observer::makeObserver(
44+
return makeObserver(
2745
[creator_2 = std::forward<F>(creator)]() mutable {
2846
return std::make_shared<ResultOfNoObserverUnwrap<F>>(creator_2());
29-
});
47+
},
48+
Core::CreatorContext{&typeid(F)});
49+
}
50+
51+
template <typename F>
52+
observer::Observer<ResultOfUnwrapSharedPtr<F>> makeValueObserver(
53+
F&& creator,
54+
std::optional<Core::CreatorContext> creatorContext = std::nullopt) {
55+
if (!creatorContext) {
56+
creatorContext = Core::CreatorContext{&typeid(F)};
57+
}
58+
return makeObserver(
59+
[activeValue = std::shared_ptr<const ResultOfUnwrapSharedPtr<F>>(),
60+
creator_2 = std::forward<F>(creator)]() mutable {
61+
auto newValue = creator_2();
62+
if (!activeValue || !(*activeValue == *newValue)) {
63+
activeValue = newValue;
64+
}
65+
return activeValue;
66+
},
67+
std::move(creatorContext));
3068
}
3169

3270
template <typename F>
3371
observer::Observer<ResultOfNoObserverUnwrap<F>> makeValueObserver(F&& creator) {
34-
return observer::makeValueObserver(
72+
return makeValueObserver(
3573
[creator_2 = std::forward<F>(creator)]() mutable {
3674
return std::make_shared<ResultOfNoObserverUnwrap<F>>(creator_2());
37-
});
75+
},
76+
Core::CreatorContext{&typeid(F)});
3877
}
3978
} // namespace observer_detail
4079

@@ -80,14 +119,7 @@ Observer<T> unwrapValue(Observer<Observer<T>> oo) {
80119
template <typename F>
81120
Observer<observer_detail::ResultOfUnwrapSharedPtr<F>> makeObserver(
82121
F&& creator) {
83-
auto core = observer_detail::Core::create(
84-
[creator_2 = std::forward<F>(creator)]() mutable {
85-
return std::static_pointer_cast<const void>(creator_2());
86-
});
87-
88-
observer_detail::ObserverManager::initCore(core);
89-
90-
return Observer<observer_detail::ResultOfUnwrapSharedPtr<F>>(core);
122+
return observer_detail::makeObserver(std::forward<F>(creator));
91123
}
92124

93125
template <typename F>
@@ -277,16 +309,7 @@ Observer<observer_detail::ResultOfUnwrapObserver<F>> makeValueObserver(
277309
template <typename F>
278310
Observer<observer_detail::ResultOfUnwrapSharedPtr<F>> makeValueObserver(
279311
F&& creator) {
280-
return makeObserver(
281-
[activeValue =
282-
std::shared_ptr<const observer_detail::ResultOfUnwrapSharedPtr<F>>(),
283-
creator_2 = std::forward<F>(creator)]() mutable {
284-
auto newValue = creator_2();
285-
if (!activeValue || !(*activeValue == *newValue)) {
286-
activeValue = newValue;
287-
}
288-
return activeValue;
289-
});
312+
return observer_detail::makeValueObserver(std::forward<F>(creator));
290313
}
291314

292315
} // namespace observer

third-party/folly/src/folly/observer/Observer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ class Observer {
246246
[[nodiscard]] CallbackHandle addCallback(
247247
Function<void(Snapshot<T>)> callback) const;
248248

249+
const std::type_info* getCreatorTypeInfo() const {
250+
return core_->getCreatorContext().typeInfo;
251+
}
252+
249253
private:
250254
template <typename Observable, typename Traits>
251255
friend class ObserverCreator;

third-party/folly/src/folly/observer/detail/Core.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,11 @@ void Core::setForceRefresh() {
147147
forceRefresh_ = true;
148148
}
149149

150-
Core::Core(folly::Function<std::shared_ptr<const void>()> creator)
151-
: creator_(std::move(creator)) {}
150+
Core::Core(
151+
folly::Function<std::shared_ptr<const void>()> creator,
152+
CreatorContext creatorContext)
153+
: creator_(std::move(creator)),
154+
creatorContext_(std::move(creatorContext)) {}
152155

153156
Core::~Core() {
154157
dependencies_.withWLock([](const Dependencies& dependencies) {
@@ -158,8 +161,11 @@ Core::~Core() {
158161
});
159162
}
160163

161-
Core::Ptr Core::create(folly::Function<std::shared_ptr<const void>()> creator) {
162-
auto core = Core::Ptr(new Core(std::move(creator)));
164+
Core::Ptr Core::create(
165+
folly::Function<std::shared_ptr<const void>()> creator,
166+
CreatorContext creatorContext) {
167+
auto core =
168+
Core::Ptr(new Core(std::move(creator), std::move(creatorContext)));
163169
return core;
164170
}
165171

third-party/folly/src/folly/observer/detail/Core.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,15 @@ class Core : public std::enable_shared_from_this<Core> {
4141
using Ptr = std::shared_ptr<Core>;
4242
using WeakPtr = std::weak_ptr<Core>;
4343

44+
struct CreatorContext {
45+
const std::type_info* typeInfo;
46+
};
4447
/**
4548
* Blocks until creator is successfully run by ObserverManager
4649
*/
47-
static Ptr create(folly::Function<std::shared_ptr<const void>()> creator);
50+
static Ptr create(
51+
folly::Function<std::shared_ptr<const void>()> creator,
52+
CreatorContext creatorContext);
4853

4954
/**
5055
* View of the observed object and its version
@@ -90,10 +95,14 @@ class Core : public std::enable_shared_from_this<Core> {
9095
*/
9196
void setForceRefresh();
9297

98+
const CreatorContext& getCreatorContext() const { return creatorContext_; }
99+
93100
~Core();
94101

95102
private:
96-
explicit Core(folly::Function<std::shared_ptr<const void>()> creator);
103+
Core(
104+
folly::Function<std::shared_ptr<const void>()> creator,
105+
CreatorContext creatorContext);
97106

98107
void addDependent(Core::WeakPtr dependent);
99108
void maybeRemoveStaleDependents();
@@ -114,6 +123,8 @@ class Core : public std::enable_shared_from_this<Core> {
114123

115124
folly::Function<std::shared_ptr<const void>()> creator_;
116125

126+
CreatorContext creatorContext_;
127+
117128
mutable SharedMutex refreshMutex_;
118129

119130
bool forceRefresh_{false};

third-party/folly/src/folly/observer/test/ObserverTest.cpp

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <thread>
2121

2222
#include <utility>
23+
#include <folly/Demangle.h>
2324
#include <folly/Singleton.h>
2425
#include <folly/fibers/FiberManager.h>
2526
#include <folly/fibers/FiberManagerMap.h>
@@ -29,11 +30,12 @@
2930
#include <folly/observer/ReadMostlyTLObserver.h>
3031
#include <folly/observer/SimpleObservable.h>
3132
#include <folly/observer/WithJitter.h>
33+
#include <folly/portability/GMock.h>
3234
#include <folly/portability/GTest.h>
3335
#include <folly/synchronization/Baton.h>
3436

3537
using namespace std::literals;
36-
using namespace folly::observer;
38+
using ::testing::StartsWith;
3739

3840
namespace {
3941

@@ -42,6 +44,9 @@ struct AltAtomic : std::atomic<T> {};
4244

4345
} // namespace
4446

47+
namespace folly {
48+
namespace observer {
49+
4550
TEST(Observer, Observable) {
4651
SimpleObservable<int> observable(42);
4752
auto observer = observable.getObserver();
@@ -1209,3 +1214,84 @@ TEST(Observer, ReenableSingletonWithPendingUpdate) {
12091214
std::this_thread::sleep_for(std::chrono::milliseconds{100});
12101215
EXPECT_EQ(42, **observer);
12111216
}
1217+
1218+
TEST(Observer, TestMakeObserverWithTypeInfo) {
1219+
const std::string prefix =
1220+
"folly::observer::Observer_TestMakeObserverWithTypeInfo_Test";
1221+
{
1222+
auto observer = folly::observer::makeObserver([] { return 42; });
1223+
EXPECT_EQ(42, **observer);
1224+
EXPECT_THAT(
1225+
folly::demangle(*observer.getCreatorTypeInfo()).toStdString(),
1226+
StartsWith(prefix));
1227+
}
1228+
{
1229+
auto observer = folly::observer::makeObserver([] {
1230+
return std::make_shared<int>(42);
1231+
});
1232+
EXPECT_EQ(42, **observer);
1233+
EXPECT_THAT(
1234+
folly::demangle(*observer.getCreatorTypeInfo()).toStdString(),
1235+
StartsWith(prefix));
1236+
}
1237+
{
1238+
auto observer1 = folly::observer::makeObserver([] { return 1; });
1239+
auto observer = folly::observer::makeObserver([observer1] {
1240+
return observer1;
1241+
});
1242+
EXPECT_EQ(1, **observer);
1243+
EXPECT_THAT(
1244+
folly::demangle(*observer1.getCreatorTypeInfo()).toStdString(),
1245+
StartsWith(prefix));
1246+
EXPECT_THAT(
1247+
folly::demangle(*observer.getCreatorTypeInfo()).toStdString(),
1248+
StartsWith("folly::observer::unwrap"));
1249+
}
1250+
}
1251+
1252+
TEST(Observer, TestMakeValueObserverWithTypeInfo) {
1253+
const std::string prefix =
1254+
"folly::observer::Observer_TestMakeValueObserverWithTypeInfo_Test";
1255+
{
1256+
auto observer = folly::observer::makeValueObserver([] { return 42; });
1257+
EXPECT_EQ(42, **observer);
1258+
EXPECT_THAT(
1259+
folly::demangle(*observer.getCreatorTypeInfo()).toStdString(),
1260+
StartsWith(prefix));
1261+
}
1262+
{
1263+
auto observer = folly::observer::makeValueObserver([] {
1264+
return std::make_shared<int>(42);
1265+
});
1266+
EXPECT_EQ(42, **observer);
1267+
EXPECT_THAT(
1268+
folly::demangle(*observer.getCreatorTypeInfo()).toStdString(),
1269+
StartsWith(prefix));
1270+
}
1271+
{
1272+
auto observer1 = folly::observer::makeValueObserver([] { return 1; });
1273+
auto observer = folly::observer::makeValueObserver([observer1] {
1274+
return observer1;
1275+
});
1276+
EXPECT_EQ(1, **observer);
1277+
EXPECT_THAT(
1278+
folly::demangle(*observer1.getCreatorTypeInfo()).toStdString(),
1279+
StartsWith(prefix));
1280+
EXPECT_THAT(
1281+
folly::demangle(*observer.getCreatorTypeInfo()).toStdString(),
1282+
StartsWith("folly::observer::unwrap"));
1283+
}
1284+
}
1285+
1286+
TEST(Observer, TestSimpleObservableWithTypeInfo) {
1287+
const std::string prefix = "folly::observer::ObserverCreator";
1288+
folly::observer::SimpleObservable<int> observable{42};
1289+
auto observer = observable.getObserver();
1290+
EXPECT_EQ(42, **observer);
1291+
EXPECT_THAT(
1292+
folly::demangle(*observer.getCreatorTypeInfo()).toStdString(),
1293+
StartsWith(prefix));
1294+
}
1295+
1296+
} // namespace observer
1297+
} // namespace folly

0 commit comments

Comments
 (0)