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

Side by Side Diff: chrome/browser/sync/weak_handle.cc

Issue 7572010: [Sync] Avoid leaking in WeakHandle even when the owner thread is gone (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "chrome/browser/sync/weak_handle.h" 5 #include "chrome/browser/sync/weak_handle.h"
6 6
7 #include <sstream>
8
9 #include "base/message_loop_proxy.h"
10 #include "base/tracked.h"
11
7 namespace browser_sync { 12 namespace browser_sync {
8 13
9 namespace internal { 14 namespace internal {
10 15
11 WeakHandleCoreBase::WeakHandleCoreBase() 16 WeakHandleCoreBase::WeakHandleCoreBase()
12 : message_loop_proxy_( 17 : owner_loop_(MessageLoop::current()),
13 base::MessageLoopProxy::CreateForCurrentThread()) {} 18 owner_loop_proxy_(base::MessageLoopProxy::CreateForCurrentThread()),
14 19 destroyed_on_owner_thread_(false) {
15 WeakHandleCoreBase::~WeakHandleCoreBase() {} 20 owner_loop_->AddDestructionObserver(this);
21 }
16 22
17 bool WeakHandleCoreBase::IsOnOwnerThread() const { 23 bool WeakHandleCoreBase::IsOnOwnerThread() const {
18 return message_loop_proxy_->BelongsToCurrentThread(); 24 // We can't use |owner_loop_proxy_->BelongsToCurrentThread()| as
25 // it may not work from within a MessageLoop::DestructionObserver
26 // callback.
27 return MessageLoop::current() == owner_loop_;
19 } 28 }
20 29
21 void WeakHandleCoreBase::PostOnOwnerThread( 30 void WeakHandleCoreBase::WillDestroyCurrentMessageLoop() {
31 CHECK(IsOnOwnerThread());
32 CHECK(!destroyed_on_owner_thread_);
33 DestroyOnOwnerThread();
Nicolas Zea 2011/08/04 19:54:10 What's the purpose to this call? All DestroyOnOwne
akalin 2011/08/04 21:56:53 Not quite. It's overridden by WeakHandle (to dest
34 CHECK(destroyed_on_owner_thread_);
35 }
36
37 WeakHandleCoreBase::~WeakHandleCoreBase() {
38 // It is safe to read |destroyed_on_owner_thread_| here even if
39 // we're not on the owner thread (see comments on
40 // base::AtomicRefCountDecN()).
41 CHECK(destroyed_on_owner_thread_);
42 }
43
44 void WeakHandleCoreBase::DestroyOnOwnerThread() {
45 CHECK(IsOnOwnerThread());
46 CHECK(!destroyed_on_owner_thread_);
47 owner_loop_->RemoveDestructionObserver(this);
48 destroyed_on_owner_thread_ = true;
49 }
50
51 namespace {
52
53 // TODO(akalin): Merge with similar function in
54 // js_transaction_observer.cc.
55 std::string GetLocationString(const tracked_objects::Location& location) {
56 std::ostringstream oss;
57 oss << location.function_name() << "@"
58 << location.file_name() << ":" << location.line_number();
59 return oss.str();
60 }
61
62 } // namespace
63
64 void WeakHandleCoreBase::PostToOwnerThread(
22 const tracked_objects::Location& from_here, 65 const tracked_objects::Location& from_here,
23 const base::Closure& fn) const { 66 const base::Closure& fn) const {
24 ignore_result(message_loop_proxy_->PostTask(from_here, fn)); 67 if (!owner_loop_proxy_->PostTask(from_here, fn)) {
68 VLOG(1) << "Could not post task from " << GetLocationString(from_here);
69 }
70 }
71
72 void WeakHandleCoreBase::DestroyAndDelete() {
73 if (IsOnOwnerThread()) {
74 CHECK(!destroyed_on_owner_thread_);
75 DestroyAndDeleteOnOwnerThread();
76 } else if (!owner_loop_proxy_->PostTask(
77 FROM_HERE,
78 base::Bind(&WeakHandleCoreBase::DestroyAndDeleteOnOwnerThread,
79 base::Unretained(this)))) {
80 // If the post fails, that means that the owner loop is gone and
81 // therefore DestroyOnOwnerThread() should have already been
82 // called via WillDestroyCurrentMessageLoop().
83 delete this;
84 }
85 }
86
87 void WeakHandleCoreBase::DestroyAndDeleteOnOwnerThread() {
88 CHECK(IsOnOwnerThread());
89 CHECK(!destroyed_on_owner_thread_);
90 DestroyOnOwnerThread();
91 CHECK(destroyed_on_owner_thread_);
92 delete this;
93 }
94
95 void WeakHandleCoreBaseTraits::Destruct(const WeakHandleCoreBase* core_base) {
96 const_cast<WeakHandleCoreBase*>(core_base)->DestroyAndDelete();
25 } 97 }
26 98
27 } // namespace internal 99 } // namespace internal
28 100
29 } // namespace base 101 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698