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

Side by Side Diff: third_party/WebKit/Source/modules/fetch/CrossThreadHolder.h

Issue 2080623002: Revert "Remove OwnPtr from Blink." (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 #ifndef CrossThreadHolder_h 5 #ifndef CrossThreadHolder_h
6 #define CrossThreadHolder_h 6 #define CrossThreadHolder_h
7 7
8 #include "core/dom/ActiveDOMObject.h" 8 #include "core/dom/ActiveDOMObject.h"
9 #include "core/dom/CrossThreadTask.h" 9 #include "core/dom/CrossThreadTask.h"
10 #include "core/dom/ExecutionContext.h" 10 #include "core/dom/ExecutionContext.h"
11 #include "public/platform/WebTraceLocation.h" 11 #include "public/platform/WebTraceLocation.h"
12 #include "wtf/Locker.h" 12 #include "wtf/Locker.h"
13 #include "wtf/OwnPtr.h"
14 #include "wtf/PassOwnPtr.h"
13 #include "wtf/PassRefPtr.h" 15 #include "wtf/PassRefPtr.h"
14 #include "wtf/PtrUtil.h"
15 #include "wtf/RefPtr.h" 16 #include "wtf/RefPtr.h"
16 #include "wtf/ThreadingPrimitives.h" 17 #include "wtf/ThreadingPrimitives.h"
17 #include <memory>
18 18
19 namespace blink { 19 namespace blink {
20 20
21 // CrossThreadHolder<T> provides cross-thread access to |obj| of class T 21 // CrossThreadHolder<T> provides cross-thread access to |obj| of class T
22 // bound to the thread of |executionContext| where |obj| is created. 22 // bound to the thread of |executionContext| where |obj| is created.
23 // - CrossThreadHolder<T> can be passed across threads. 23 // - CrossThreadHolder<T> can be passed across threads.
24 // - |obj|'s methods are called on the thread of |executionContext| 24 // - |obj|'s methods are called on the thread of |executionContext|
25 // via CrossThreadHolder<T>::postTask(). 25 // via CrossThreadHolder<T>::postTask().
26 // - |obj| is destructed on the thread of |executionContext| 26 // - |obj| is destructed on the thread of |executionContext|
27 // when |executionContext| is stopped or 27 // when |executionContext| is stopped or
28 // CrossThreadHolder is destructed (earlier of them). 28 // CrossThreadHolder is destructed (earlier of them).
29 // Note: |obj|'s destruction can be slightly after CrossThreadHolder. 29 // Note: |obj|'s destruction can be slightly after CrossThreadHolder.
30 template<typename T> 30 template<typename T>
31 class CrossThreadHolder final { 31 class CrossThreadHolder final {
32 public: 32 public:
33 // Must be called on the thread where |obj| is created 33 // Must be called on the thread where |obj| is created
34 // (== the thread of |executionContext|). 34 // (== the thread of |executionContext|).
35 // The current thread must be attached to Oilpan. 35 // The current thread must be attached to Oilpan.
36 static std::unique_ptr<CrossThreadHolder<T>> create(ExecutionContext* execut ionContext, std::unique_ptr<T> obj) 36 static PassOwnPtr<CrossThreadHolder<T>> create(ExecutionContext* executionCo ntext, PassOwnPtr<T> obj)
37 { 37 {
38 ASSERT(executionContext->isContextThread()); 38 ASSERT(executionContext->isContextThread());
39 return wrapUnique(new CrossThreadHolder(executionContext, std::move(obj) )); 39 return adoptPtr(new CrossThreadHolder(executionContext, std::move(obj))) ;
40 } 40 }
41 41
42 // Can be called from any thread. 42 // Can be called from any thread.
43 // Executes |task| with |obj| and |executionContext| on the thread of 43 // Executes |task| with |obj| and |executionContext| on the thread of
44 // |executionContext|. 44 // |executionContext|.
45 // NOTE: |task| might be silently ignored (i.e. not executed) and 45 // NOTE: |task| might be silently ignored (i.e. not executed) and
46 // destructed (possibly on the calling thread or on the thread of 46 // destructed (possibly on the calling thread or on the thread of
47 // |executionContext|) when |executionContext| is stopped or 47 // |executionContext|) when |executionContext| is stopped or
48 // CrossThreadHolder is destructed. 48 // CrossThreadHolder is destructed.
49 void postTask(std::unique_ptr<WTF::Function<void(T*, ExecutionContext*), WTF ::CrossThreadAffinity>> task) 49 void postTask(std::unique_ptr<WTF::Function<void(T*, ExecutionContext*), WTF ::CrossThreadAffinity>> task)
50 { 50 {
51 MutexLocker locker(m_mutex->mutex()); 51 MutexLocker locker(m_mutex->mutex());
52 if (!m_bridge) { 52 if (!m_bridge) {
53 // The bridge has already disappeared. 53 // The bridge has already disappeared.
54 return; 54 return;
55 } 55 }
56 m_bridge->getExecutionContext()->postTask(BLINK_FROM_HERE, createCrossTh readTask(&Bridge::runTask, wrapCrossThreadPersistent(m_bridge.get()), passed(std ::move(task)))); 56 m_bridge->getExecutionContext()->postTask(BLINK_FROM_HERE, createCrossTh readTask(&Bridge::runTask, wrapCrossThreadPersistent(m_bridge.get()), passed(std ::move(task))));
57 } 57 }
58 58
59 ~CrossThreadHolder() 59 ~CrossThreadHolder()
60 { 60 {
61 MutexLocker locker(m_mutex->mutex()); 61 MutexLocker locker(m_mutex->mutex());
62 clearInternal(); 62 clearInternal();
63 } 63 }
64 64
65 private: 65 private:
66 // Object graph: 66 // Object graph:
67 // +------+ +-----------------+ 67 // +------+ +-----------------+
68 // T <-std::unique_ptr- |Bridge| ---------*-------------> |CrossThreadHo lder| 68 // T <-OwnPtr- |Bridge| ---------*-------------> |CrossThreadHolder|
69 // | | <-CrossThreadPersistent- | | 69 // | | <-CrossThreadPersistent- | |
70 // +------+ +-----------------+ 70 // +------+ +-----------------+
71 // | | 71 // | |
72 // +--RefPtr--> MutexWrapper <--RefPtr--+ 72 // +--RefPtr--> MutexWrapper <--RefPtr--+
73 // The CrossThreadPersistent<T>/T* between CrossThreadHolder and Bridge 73 // The CrossThreadPersistent<T>/T* between CrossThreadHolder and Bridge
74 // are protected by MutexWrapper 74 // are protected by MutexWrapper
75 // and cleared when CrossThreadHolder::clearInternal() is called, i.e.: 75 // and cleared when CrossThreadHolder::clearInternal() is called, i.e.:
76 // [1] when |executionContext| is stopped, or 76 // [1] when |executionContext| is stopped, or
77 // [2] when CrossThreadHolder is destructed. 77 // [2] when CrossThreadHolder is destructed.
78 // Then Bridge is shortly garbage collected and T is destructed. 78 // Then Bridge is shortly garbage collected and T is destructed.
79 79
80 class MutexWrapper : public ThreadSafeRefCounted<MutexWrapper> { 80 class MutexWrapper : public ThreadSafeRefCounted<MutexWrapper> {
81 public: 81 public:
82 static PassRefPtr<MutexWrapper> create() { return adoptRef(new MutexWrap per()); } 82 static PassRefPtr<MutexWrapper> create() { return adoptRef(new MutexWrap per()); }
83 Mutex& mutex() { return m_mutex; } 83 Mutex& mutex() { return m_mutex; }
84 private: 84 private:
85 MutexWrapper() = default; 85 MutexWrapper() = default;
86 Mutex m_mutex; 86 Mutex m_mutex;
87 }; 87 };
88 88
89 // All methods except for clearInternal() 89 // All methods except for clearInternal()
90 // must be called on |executionContext|'s thread. 90 // must be called on |executionContext|'s thread.
91 class Bridge 91 class Bridge
92 : public GarbageCollectedFinalized<Bridge> 92 : public GarbageCollectedFinalized<Bridge>
93 , public ActiveDOMObject { 93 , public ActiveDOMObject {
94 USING_GARBAGE_COLLECTED_MIXIN(Bridge); 94 USING_GARBAGE_COLLECTED_MIXIN(Bridge);
95 public: 95 public:
96 Bridge(ExecutionContext* executionContext, std::unique_ptr<T> obj, PassR efPtr<MutexWrapper> mutex, CrossThreadHolder* holder) 96 Bridge(ExecutionContext* executionContext, PassOwnPtr<T> obj, PassRefPtr <MutexWrapper> mutex, CrossThreadHolder* holder)
97 : ActiveDOMObject(executionContext) 97 : ActiveDOMObject(executionContext)
98 , m_obj(std::move(obj)) 98 , m_obj(std::move(obj))
99 , m_mutex(mutex) 99 , m_mutex(mutex)
100 , m_holder(holder) 100 , m_holder(holder)
101 { 101 {
102 suspendIfNeeded(); 102 suspendIfNeeded();
103 } 103 }
104 104
105 DEFINE_INLINE_TRACE() 105 DEFINE_INLINE_TRACE()
106 { 106 {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 ASSERT(!m_holder); 138 ASSERT(!m_holder);
139 } 139 }
140 140
141 // We have to destruct |*m_obj| here because destructing |*m_obj| 141 // We have to destruct |*m_obj| here because destructing |*m_obj|
142 // in ~Bridge() might be too late when |executionContext| is 142 // in ~Bridge() might be too late when |executionContext| is
143 // stopped. 143 // stopped.
144 m_obj.reset(); 144 m_obj.reset();
145 } 145 }
146 146
147 147
148 std::unique_ptr<T> m_obj; 148 OwnPtr<T> m_obj;
149 // All accesses to |m_holder| must be protected by |m_mutex|. 149 // All accesses to |m_holder| must be protected by |m_mutex|.
150 RefPtr<MutexWrapper> m_mutex; 150 RefPtr<MutexWrapper> m_mutex;
151 CrossThreadHolder* m_holder; 151 CrossThreadHolder* m_holder;
152 }; 152 };
153 153
154 // Must be protected by |m_mutex|. 154 // Must be protected by |m_mutex|.
155 void clearInternal() 155 void clearInternal()
156 { 156 {
157 if (m_bridge) 157 if (m_bridge)
158 m_bridge->clearInternal(); 158 m_bridge->clearInternal();
159 m_bridge.clear(); 159 m_bridge.clear();
160 } 160 }
161 161
162 CrossThreadHolder(ExecutionContext* executionContext, std::unique_ptr<T> obj ) 162 CrossThreadHolder(ExecutionContext* executionContext, PassOwnPtr<T> obj)
163 : m_mutex(MutexWrapper::create()) 163 : m_mutex(MutexWrapper::create())
164 , m_bridge(new Bridge(executionContext, std::move(obj), m_mutex, this)) 164 , m_bridge(new Bridge(executionContext, std::move(obj), m_mutex, this))
165 { 165 {
166 } 166 }
167 167
168 RefPtr<MutexWrapper> m_mutex; 168 RefPtr<MutexWrapper> m_mutex;
169 // |m_bridge| is protected by |m_mutex|. 169 // |m_bridge| is protected by |m_mutex|.
170 // |m_bridge| is cleared before the thread that allocated |*m_bridge| 170 // |m_bridge| is cleared before the thread that allocated |*m_bridge|
171 // is stopped. 171 // is stopped.
172 CrossThreadPersistent<Bridge> m_bridge; 172 CrossThreadPersistent<Bridge> m_bridge;
173 }; 173 };
174 174
175 } // namespace blink 175 } // namespace blink
176 176
177 #endif // CrossThreadHolder_h 177 #endif // CrossThreadHolder_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698