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