OLD | NEW |
---|---|
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 |
OLD | NEW |