1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_DEATH_AWARE_SCRIPT_WRAPPABLE_H_
6 #define THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_DEATH_AWARE_SCRIPT_WRAPPABLE_H_
7 
8 #include <signal.h>
9 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
10 #include "third_party/blink/renderer/platform/heap/heap.h"
11 
12 namespace blink {
13 
14 class DeathAwareScriptWrappable;
15 
16 namespace internal {
17 
18 class InObjectContainer {
19   DISALLOW_NEW();
20 
21  public:
InObjectContainer(DeathAwareScriptWrappable * dependency)22   explicit InObjectContainer(DeathAwareScriptWrappable* dependency)
23       : dependency_(dependency) {}
24 
~InObjectContainer()25   virtual ~InObjectContainer() {}
26 
Trace(Visitor * visitor)27   virtual void Trace(Visitor* visitor) { visitor->Trace(dependency_); }
28 
29  private:
30   Member<DeathAwareScriptWrappable> dependency_;
31 };
32 
33 }  // namespace internal
34 
35 // ScriptWrappable that can be used to
36 // (a) build a graph of ScriptWrappables, and
37 // (b) observe a single DeathAwareScriptWrappable for being garbage collected.
38 class DeathAwareScriptWrappable : public ScriptWrappable {
39   DEFINE_WRAPPERTYPEINFO();
40   static DeathAwareScriptWrappable* instance_;
41   static bool has_died_;
42 
43  public:
44   typedef Member<DeathAwareScriptWrappable> Wrapper;
45 
HasDied()46   static bool HasDied() { return has_died_; }
ObserveDeathsOf(DeathAwareScriptWrappable * instance)47   static void ObserveDeathsOf(DeathAwareScriptWrappable* instance) {
48     has_died_ = false;
49     instance_ = instance;
50   }
51 
52   DeathAwareScriptWrappable() = default;
~DeathAwareScriptWrappable()53   ~DeathAwareScriptWrappable() override {
54     if (this == instance_) {
55       has_died_ = true;
56     }
57   }
58 
Trace(Visitor * visitor)59   void Trace(Visitor* visitor) override {
60     visitor->Trace(wrapped_dependency_);
61     visitor->Trace(wrapped_vector_dependency_);
62     visitor->Trace(wrapped_hash_map_dependency_);
63     visitor->Trace(in_object_dependency_);
64     ScriptWrappable::Trace(visitor);
65   }
66 
SetWrappedDependency(DeathAwareScriptWrappable * dependency)67   void SetWrappedDependency(DeathAwareScriptWrappable* dependency) {
68     wrapped_dependency_ = dependency;
69   }
70 
AddWrappedVectorDependency(DeathAwareScriptWrappable * dependency)71   void AddWrappedVectorDependency(DeathAwareScriptWrappable* dependency) {
72     wrapped_vector_dependency_.push_back(dependency);
73   }
74 
AddWrappedHashMapDependency(DeathAwareScriptWrappable * key,DeathAwareScriptWrappable * value)75   void AddWrappedHashMapDependency(DeathAwareScriptWrappable* key,
76                                    DeathAwareScriptWrappable* value) {
77     wrapped_hash_map_dependency_.insert(key, value);
78   }
79 
AddInObjectDependency(DeathAwareScriptWrappable * dependency)80   void AddInObjectDependency(DeathAwareScriptWrappable* dependency) {
81     in_object_dependency_.push_back(internal::InObjectContainer(dependency));
82   }
83 
84  private:
85   Wrapper wrapped_dependency_;
86   HeapVector<Wrapper> wrapped_vector_dependency_;
87   HeapHashMap<Wrapper, Wrapper> wrapped_hash_map_dependency_;
88   HeapVector<internal::InObjectContainer> in_object_dependency_;
89 };
90 
91 }  // namespace blink
92 
93 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_DEATH_AWARE_SCRIPT_WRAPPABLE_H_
94