OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 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 #ifndef CCScopedThreadProxy_h | 5 #ifndef CCScopedThreadProxy_h |
6 #define CCScopedThreadProxy_h | 6 #define CCScopedThreadProxy_h |
7 | 7 |
8 #include "CCThreadTask.h" | 8 #include "CCThreadTask.h" |
| 9 #include "base/logging.h" |
9 #include "base/threading/platform_thread.h" | 10 #include "base/threading/platform_thread.h" |
10 #include <wtf/OwnPtr.h> | 11 #include <wtf/OwnPtr.h> |
11 #include <wtf/PassOwnPtr.h> | 12 #include <wtf/PassOwnPtr.h> |
12 #include <wtf/ThreadSafeRefCounted.h> | 13 #include <wtf/ThreadSafeRefCounted.h> |
13 | 14 |
14 namespace cc { | 15 namespace cc { |
15 | 16 |
16 // This class is a proxy used to post tasks to an target thread from any other t
hread. The proxy may be shut down at | 17 // This class is a proxy used to post tasks to an target thread from any other t
hread. The proxy may be shut down at |
17 // any point from the target thread after which no more tasks posted to the prox
y will run. In other words, all | 18 // any point from the target thread after which no more tasks posted to the prox
y will run. In other words, all |
18 // tasks posted via a proxy are scoped to the lifecycle of the proxy. Use this w
hen posting tasks to an object that | 19 // tasks posted via a proxy are scoped to the lifecycle of the proxy. Use this w
hen posting tasks to an object that |
19 // might die with tasks in flight. | 20 // might die with tasks in flight. |
20 // | 21 // |
21 // The proxy must be created and shut down from the target thread, tasks may be
posted from any thread. | 22 // The proxy must be created and shut down from the target thread, tasks may be
posted from any thread. |
22 // | 23 // |
23 // Implementation note: Unlike ScopedRunnableMethodFactory in Chromium, pending
tasks are not cancelled by actually | 24 // Implementation note: Unlike ScopedRunnableMethodFactory in Chromium, pending
tasks are not cancelled by actually |
24 // destroying the proxy. Instead each pending task holds a reference to the prox
y to avoid maintaining an explicit | 25 // destroying the proxy. Instead each pending task holds a reference to the prox
y to avoid maintaining an explicit |
25 // list of outstanding tasks. | 26 // list of outstanding tasks. |
26 class CCScopedThreadProxy : public ThreadSafeRefCounted<CCScopedThreadProxy> { | 27 class CCScopedThreadProxy : public ThreadSafeRefCounted<CCScopedThreadProxy> { |
27 public: | 28 public: |
28 static PassRefPtr<CCScopedThreadProxy> create(CCThread* targetThread) | 29 static PassRefPtr<CCScopedThreadProxy> create(CCThread* targetThread) |
29 { | 30 { |
30 ASSERT(base::PlatformThread::CurrentId() == targetThread->threadID()); | 31 DCHECK(base::PlatformThread::CurrentId() == targetThread->threadID()); |
31 return adoptRef(new CCScopedThreadProxy(targetThread)); | 32 return adoptRef(new CCScopedThreadProxy(targetThread)); |
32 } | 33 } |
33 | 34 |
34 ~CCScopedThreadProxy(); | 35 ~CCScopedThreadProxy(); |
35 | 36 |
36 // Can be called from any thread. Posts a task to the target thread that run
s unless | 37 // Can be called from any thread. Posts a task to the target thread that run
s unless |
37 // shutdown() is called before it runs. | 38 // shutdown() is called before it runs. |
38 void postTask(PassOwnPtr<CCThread::Task> task) | 39 void postTask(PassOwnPtr<CCThread::Task> task) |
39 { | 40 { |
40 ref(); | 41 ref(); |
41 m_targetThread->postTask(createCCThreadTask(this, &CCScopedThreadProxy::
runTaskIfNotShutdown, task)); | 42 m_targetThread->postTask(createCCThreadTask(this, &CCScopedThreadProxy::
runTaskIfNotShutdown, task)); |
42 } | 43 } |
43 | 44 |
44 void shutdown() | 45 void shutdown() |
45 { | 46 { |
46 ASSERT(base::PlatformThread::CurrentId() == m_targetThread->threadID()); | 47 DCHECK(base::PlatformThread::CurrentId() == m_targetThread->threadID()); |
47 ASSERT(!m_shutdown); | 48 DCHECK(!m_shutdown); |
48 m_shutdown = true; | 49 m_shutdown = true; |
49 } | 50 } |
50 | 51 |
51 private: | 52 private: |
52 explicit CCScopedThreadProxy(CCThread* targetThread); | 53 explicit CCScopedThreadProxy(CCThread* targetThread); |
53 | 54 |
54 void runTaskIfNotShutdown(PassOwnPtr<CCThread::Task> popTask) | 55 void runTaskIfNotShutdown(PassOwnPtr<CCThread::Task> popTask) |
55 { | 56 { |
56 OwnPtr<CCThread::Task> task = popTask; | 57 OwnPtr<CCThread::Task> task = popTask; |
57 // If our shutdown flag is set, it's possible that m_targetThread has al
ready been destroyed so don't | 58 // If our shutdown flag is set, it's possible that m_targetThread has al
ready been destroyed so don't |
58 // touch it. | 59 // touch it. |
59 if (m_shutdown) { | 60 if (m_shutdown) { |
60 deref(); | 61 deref(); |
61 return; | 62 return; |
62 } | 63 } |
63 ASSERT(base::PlatformThread::CurrentId() == m_targetThread->threadID()); | 64 DCHECK(base::PlatformThread::CurrentId() == m_targetThread->threadID()); |
64 task->performTask(); | 65 task->performTask(); |
65 deref(); | 66 deref(); |
66 } | 67 } |
67 | 68 |
68 CCThread* m_targetThread; | 69 CCThread* m_targetThread; |
69 bool m_shutdown; // Only accessed on the target thread | 70 bool m_shutdown; // Only accessed on the target thread |
70 }; | 71 }; |
71 | 72 |
72 } | 73 } |
73 | 74 |
74 #endif | 75 #endif |
OLD | NEW |