Core.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * Copyright 2016-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #pragma once
  17. #include <folly/Function.h>
  18. #include <folly/Synchronized.h>
  19. #include <folly/futures/Future.h>
  20. #include <atomic>
  21. #include <memory>
  22. #include <mutex>
  23. #include <unordered_set>
  24. #include <utility>
  25. #include <vector>
  26. namespace folly {
  27. namespace observer_detail {
  28. class ObserverManager;
  29. /**
  30. * Core stores the current version of the object held by Observer. It also keeps
  31. * all dependencies and dependents of the Observer.
  32. */
  33. class Core : public std::enable_shared_from_this<Core> {
  34. public:
  35. using Ptr = std::shared_ptr<Core>;
  36. using WeakPtr = std::weak_ptr<Core>;
  37. /**
  38. * Blocks until creator is successfully run by ObserverManager
  39. */
  40. static Ptr create(folly::Function<std::shared_ptr<const void>()> creator);
  41. /**
  42. * View of the observed object and its version
  43. */
  44. struct VersionedData {
  45. VersionedData() {}
  46. VersionedData(std::shared_ptr<const void> data_, size_t version_)
  47. : data(std::move(data_)), version(version_) {}
  48. std::shared_ptr<const void> data;
  49. size_t version{0};
  50. };
  51. /**
  52. * Gets current view of the observed object.
  53. * This is safe to call from any thread. If this is called from other Observer
  54. * functor then that Observer is marked as dependent on current Observer.
  55. */
  56. VersionedData getData();
  57. /**
  58. * Gets the version of the observed object.
  59. */
  60. size_t getVersion() const {
  61. return version_;
  62. }
  63. /**
  64. * Get the last version at which the observed object was actually changed.
  65. */
  66. size_t getVersionLastChange() {
  67. return versionLastChange_;
  68. }
  69. /**
  70. * Check if the observed object needs to be re-computed. Returns the version
  71. * of last change. If force is true, re-computes the observed object, even if
  72. * dependencies didn't change.
  73. *
  74. * This should be only called from ObserverManager thread.
  75. */
  76. size_t refresh(size_t version, bool force = false);
  77. ~Core();
  78. private:
  79. explicit Core(folly::Function<std::shared_ptr<const void>()> creator);
  80. void addDependent(Core::WeakPtr dependent);
  81. void removeStaleDependents();
  82. using Dependents = std::vector<WeakPtr>;
  83. using Dependencies = std::unordered_set<Ptr>;
  84. folly::Synchronized<Dependents> dependents_;
  85. folly::Synchronized<Dependencies> dependencies_;
  86. std::atomic<size_t> version_{0};
  87. std::atomic<size_t> versionLastChange_{0};
  88. folly::Synchronized<VersionedData> data_;
  89. folly::Function<std::shared_ptr<const void>()> creator_;
  90. std::mutex refreshMutex_;
  91. };
  92. } // namespace observer_detail
  93. } // namespace folly