Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(306)

Side by Side Diff: base/memory/scoped_vector_unittest.cc

Issue 1365893002: Fix LifeCycleWatcher in ScopedVectorTest to not be referenced after being destructed. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/memory/scoped_vector.h" 5 #include "base/memory/scoped_vector.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "testing/gtest/include/gtest/gtest.h" 10 #include "testing/gtest/include/gtest/gtest.h"
11 11
12 namespace { 12 namespace {
13 13
14 // The LifeCycleObject notifies its Observer upon construction & destruction. 14 // The LifeCycleObject notifies its Observer upon construction & destruction.
15 class LifeCycleObject { 15 class LifeCycleObject {
16 public: 16 public:
17 class Observer { 17 class Observer {
18 public: 18 public:
19 virtual void OnLifeCycleConstruct(LifeCycleObject* o) = 0; 19 virtual void OnLifeCycleConstruct(LifeCycleObject* o) = 0;
20 virtual void OnLifeCycleDestroy(LifeCycleObject* o) = 0; 20 virtual void OnLifeCycleDestroy(LifeCycleObject* o) = 0;
21 21
22 protected: 22 protected:
23 virtual ~Observer() {} 23 virtual ~Observer() {}
24 }; 24 };
25 25
26 ~LifeCycleObject() { 26 ~LifeCycleObject() {
27 observer_->OnLifeCycleDestroy(this); 27 if (observer_)
28 observer_->OnLifeCycleDestroy(this);
28 } 29 }
29 30
30 private: 31 private:
31 friend class LifeCycleWatcher; 32 friend class LifeCycleWatcher;
32 33
33 explicit LifeCycleObject(Observer* observer) 34 explicit LifeCycleObject(Observer* observer)
34 : observer_(observer) { 35 : observer_(observer) {
35 observer_->OnLifeCycleConstruct(this); 36 observer_->OnLifeCycleConstruct(this);
36 } 37 }
37 38
39 void DisconnectObserver() {
40 observer_ = nullptr;
41 }
42
38 Observer* observer_; 43 Observer* observer_;
39 44
40 DISALLOW_COPY_AND_ASSIGN(LifeCycleObject); 45 DISALLOW_COPY_AND_ASSIGN(LifeCycleObject);
41 }; 46 };
42 47
43 // The life cycle states we care about for the purposes of testing ScopedVector 48 // The life cycle states we care about for the purposes of testing ScopedVector
44 // against objects. 49 // against objects.
45 enum LifeCycleState { 50 enum LifeCycleState {
46 LC_INITIAL, 51 LC_INITIAL,
47 LC_CONSTRUCTED, 52 LC_CONSTRUCTED,
48 LC_DESTROYED, 53 LC_DESTROYED,
49 }; 54 };
50 55
51 // Because we wish to watch the life cycle of an object being constructed and 56 // Because we wish to watch the life cycle of an object being constructed and
52 // destroyed, and further wish to test expectations against the state of that 57 // destroyed, and further wish to test expectations against the state of that
53 // object, we cannot save state in that object itself. Instead, we use this 58 // object, we cannot save state in that object itself. Instead, we use this
54 // pairing of the watcher, which observes the object and notifies of 59 // pairing of the watcher, which observes the object and notifies of
55 // construction & destruction. Since we also may be testing assumptions about 60 // construction & destruction. Since we also may be testing assumptions about
56 // things not getting freed, this class also acts like a scoping object and 61 // things not getting freed, this class also acts like a scoping object and
57 // deletes the |constructed_life_cycle_object_|, if any when the 62 // deletes the |constructed_life_cycle_object_|, if any when the
58 // LifeCycleWatcher is destroyed. To keep this simple, the only expected state 63 // LifeCycleWatcher is destroyed. To keep this simple, the only expected state
59 // changes are: 64 // changes are:
60 // INITIAL -> CONSTRUCTED -> DESTROYED. 65 // INITIAL -> CONSTRUCTED -> DESTROYED.
61 // Anything more complicated than that should start another test. 66 // Anything more complicated than that should start another test.
62 class LifeCycleWatcher : public LifeCycleObject::Observer { 67 class LifeCycleWatcher : public LifeCycleObject::Observer {
63 public: 68 public:
64 LifeCycleWatcher() : life_cycle_state_(LC_INITIAL) {} 69 LifeCycleWatcher() : life_cycle_state_(LC_INITIAL) {}
65 ~LifeCycleWatcher() override {} 70 ~LifeCycleWatcher() override {
71 // Stop watching the watched object. Without this, the object's destructor
danakj 2015/09/24 17:43:51 Alternatively, you could just keep the watcher ali
Anand Mistry (off Chromium) 2015/09/24 21:56:27 The two tests that fail are WeakClear and InsertRa
72 // will call into OnLifeCycleDestroy when destructed, which happens after
73 // this destructor has finished running.
74 if (constructed_life_cycle_object_)
75 constructed_life_cycle_object_->DisconnectObserver();
76 }
66 77
67 // Assert INITIAL -> CONSTRUCTED and no LifeCycleObject associated with this 78 // Assert INITIAL -> CONSTRUCTED and no LifeCycleObject associated with this
68 // LifeCycleWatcher. 79 // LifeCycleWatcher.
69 void OnLifeCycleConstruct(LifeCycleObject* object) override { 80 void OnLifeCycleConstruct(LifeCycleObject* object) override {
70 ASSERT_EQ(LC_INITIAL, life_cycle_state_); 81 ASSERT_EQ(LC_INITIAL, life_cycle_state_);
71 ASSERT_EQ(NULL, constructed_life_cycle_object_.get()); 82 ASSERT_EQ(NULL, constructed_life_cycle_object_.get());
72 life_cycle_state_ = LC_CONSTRUCTED; 83 life_cycle_state_ = LC_CONSTRUCTED;
73 constructed_life_cycle_object_.reset(object); 84 constructed_life_cycle_object_.reset(object);
74 } 85 }
75 86
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 EXPECT_EQ(0, delete_counter); 326 EXPECT_EQ(0, delete_counter);
316 { 327 {
317 ScopedVector<DeleteCounter> v; 328 ScopedVector<DeleteCounter> v;
318 v.push_back(elem.Pass()); 329 v.push_back(elem.Pass());
319 EXPECT_EQ(0, delete_counter); 330 EXPECT_EQ(0, delete_counter);
320 } 331 }
321 EXPECT_EQ(1, delete_counter); 332 EXPECT_EQ(1, delete_counter);
322 } 333 }
323 334
324 } // namespace 335 } // namespace
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698