| // Copyright 2016 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROMECAST_BASE_COMPONENT_COMPONENT_INTERNAL_H_ |
| #define CHROMECAST_BASE_COMPONENT_COMPONENT_INTERNAL_H_ |
| |
| #include "base/check.h" |
| #include "base/functional/callback.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/threading/thread_checker.h" |
| |
| namespace chromecast { |
| |
| template <typename C> |
| class WeakReference; |
| |
| class ComponentBase; |
| |
| namespace subtle { |
| |
| class WeakReferenceBase; |
| |
| // Manages thread-safe dependency counting. Instances of this class are |
| // RefCountedThreadSafe since they must live as long as any dependent. |
| class DependencyCount; |
| |
| // Base class for strong dependencies. A strong dependency is tied to a |
| // specific dependent component instance. This allows dependents to be |
| // disabled before the component they depend on. May be used on any thread. |
| class DependencyBase { |
| public: |
| DependencyBase(const WeakReferenceBase& dependency, ComponentBase* dependent); |
| |
| DependencyBase(const DependencyBase&) = delete; |
| DependencyBase& operator=(const DependencyBase&) = delete; |
| |
| ~DependencyBase(); |
| |
| void StartUsing(); |
| void StopUsing(); |
| bool DependsOn(ComponentBase* component); |
| |
| protected: |
| ComponentBase* const dependent_; |
| ComponentBase* dependency_; |
| |
| private: |
| friend class DependencyCount; |
| friend class WeakReferenceBase; |
| |
| void Ready(ComponentBase* dependency); |
| void Disable(); |
| |
| const scoped_refptr<DependencyCount> counter_; |
| base::ThreadChecker thread_checker_; |
| }; |
| |
| // Base class for weak dependencies. Weak dependencies cannot be used |
| // directly; they must be converted to a strong dependency or a temp |
| // dependency first. May be converted on any thread. |
| class WeakReferenceBase { |
| protected: |
| friend class DependencyBase; |
| |
| explicit WeakReferenceBase(const ComponentBase& dependency); |
| explicit WeakReferenceBase(const DependencyBase& dependency); |
| WeakReferenceBase(const WeakReferenceBase& other); |
| WeakReferenceBase(WeakReferenceBase&& other); |
| ~WeakReferenceBase(); |
| |
| const scoped_refptr<DependencyCount> counter_; |
| }; |
| |
| // Base class for temp dependencies. Temp dependencies are meant for |
| // short-term use only, but can be used from any thread. |
| class ScopedReferenceBase { |
| protected: |
| explicit ScopedReferenceBase(const scoped_refptr<DependencyCount>& counter); |
| ScopedReferenceBase(ScopedReferenceBase&& other); |
| ~ScopedReferenceBase(); |
| |
| const scoped_refptr<DependencyCount> counter_; |
| ComponentBase* dependency_; |
| }; |
| |
| // This class is not intended to be long-lived, and should not be declared as |
| // a variable type (eg, don't use it as a member variable). Instead, use auto |
| // (see WeakReference::Try() for an example). |
| template <typename C> |
| class Ref_DO_NOT_DECLARE : public ScopedReferenceBase { |
| public: |
| Ref_DO_NOT_DECLARE(Ref_DO_NOT_DECLARE&& other) = default; |
| |
| C* operator->() const { |
| DCHECK(dependency_); |
| return static_cast<C*>(dependency_); |
| } |
| |
| explicit operator bool() const { return (dependency_ != nullptr); } |
| |
| private: |
| friend class WeakReference<C>; |
| |
| explicit Ref_DO_NOT_DECLARE(const scoped_refptr<DependencyCount>& counter) |
| : ScopedReferenceBase(counter) {} |
| |
| Ref_DO_NOT_DECLARE(const Ref_DO_NOT_DECLARE& other) = delete; |
| Ref_DO_NOT_DECLARE& operator=(const Ref_DO_NOT_DECLARE& rhs) = delete; |
| Ref_DO_NOT_DECLARE& operator=(Ref_DO_NOT_DECLARE&& rhs) = delete; |
| }; |
| |
| } // namespace subtle |
| } // namespace chromecast |
| |
| #endif // CHROMECAST_BASE_COMPONENT_COMPONENT_INTERNAL_H_ |