/*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#include <folly/experimental/observer/detail/Core.h>
+
+#include <folly/ExceptionString.h>
#include <folly/experimental/observer/detail/ObserverManager.h>
namespace folly {
size_t Core::refresh(size_t version, bool force) {
CHECK(ObserverManager::inManagerThread());
+ ObserverManager::DependencyRecorder::markRefreshDependency(*this);
+ SCOPE_EXIT {
+ ObserverManager::DependencyRecorder::unmarkRefreshDependency(*this);
+ };
+
if (version_ >= version) {
return versionLastChange_;
}
- bool refreshDependents = false;
-
{
std::lock_guard<std::mutex> lgRefresh(refreshMutex_);
bool needRefresh = force || version_ == 0;
+ ObserverManager::DependencyRecorder dependencyRecorder(*this);
+
// This can be run in parallel, but we expect most updates to propagate
// bottom to top.
dependencies_.withRLock([&](const Dependencies& dependencies) {
for (const auto& dependency : dependencies) {
- if (dependency->refresh(version) > version_) {
+ try {
+ if (dependency->refresh(version) > version_) {
+ needRefresh = true;
+ break;
+ }
+ } catch (...) {
+ LOG(ERROR) << "Exception while checking dependencies for updates: "
+ << exceptionStr(std::current_exception());
+
needRefresh = true;
break;
}
return versionLastChange_;
}
- ObserverManager::DependencyRecorder dependencyRecorder;
-
try {
{
VersionedData newData{creator_(), version};
}
versionLastChange_ = version;
- refreshDependents = true;
} catch (...) {
LOG(ERROR) << "Exception while refreshing Observer: "
<< exceptionStr(std::current_exception());
version_ = version;
+ if (versionLastChange_ != version) {
+ return versionLastChange_;
+ }
+
auto newDependencies = dependencyRecorder.release();
dependencies_.withWLock([&](Dependencies& dependencies) {
for (const auto& dependency : newDependencies) {
});
}
- if (refreshDependents) {
- auto dependents = dependents_.copy();
+ auto dependents = dependents_.copy();
- for (const auto& dependentWeak : dependents) {
- if (auto dependent = dependentWeak.lock()) {
- ObserverManager::scheduleRefresh(std::move(dependent), version);
- }
+ for (const auto& dependentWeak : dependents) {
+ if (auto dependent = dependentWeak.lock()) {
+ ObserverManager::scheduleRefresh(std::move(dependent), version);
}
}
}
});
}
-}
-}
+} // namespace observer_detail
+} // namespace folly