OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "ppapi/proxy/ppb_message_loop_proxy.h" | 5 #include "ppapi/proxy/ppb_message_loop_proxy.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
12 #include "base/threading/thread_local_storage.h" | |
13 #include "ppapi/c/dev/ppb_message_loop_dev.h" | 12 #include "ppapi/c/dev/ppb_message_loop_dev.h" |
14 #include "ppapi/c/pp_errors.h" | 13 #include "ppapi/c/pp_errors.h" |
15 #include "ppapi/proxy/plugin_dispatcher.h" | 14 #include "ppapi/proxy/plugin_dispatcher.h" |
15 #include "ppapi/proxy/plugin_globals.h" | |
16 #include "ppapi/shared_impl/resource.h" | 16 #include "ppapi/shared_impl/resource.h" |
17 #include "ppapi/thunk/enter.h" | 17 #include "ppapi/thunk/enter.h" |
18 #include "ppapi/thunk/ppb_message_loop_api.h" | 18 #include "ppapi/thunk/ppb_message_loop_api.h" |
19 | 19 |
20 using ppapi::thunk::PPB_MessageLoop_API; | 20 using ppapi::thunk::PPB_MessageLoop_API; |
21 | 21 |
22 namespace ppapi { | 22 namespace ppapi { |
23 namespace proxy { | 23 namespace proxy { |
24 | 24 |
25 namespace { | 25 namespace { |
26 | 26 |
27 typedef thunk::EnterResource<PPB_MessageLoop_API> EnterMessageLoop; | 27 typedef thunk::EnterResource<PPB_MessageLoop_API> EnterMessageLoop; |
28 | 28 |
29 static base::ThreadLocalStorage::StaticSlot tls_slot = TLS_INITIALIZER; | |
Nico
2012/02/05 03:13:37
I think this stopped needing a static initializer
brettw
2012/02/05 03:33:21
Yeah, I did this patch actually before you wrote y
| |
30 | |
31 class MessageLoopResource : public Resource, public PPB_MessageLoop_API { | 29 class MessageLoopResource : public Resource, public PPB_MessageLoop_API { |
32 public: | 30 public: |
33 MessageLoopResource(PP_Instance instance); | 31 MessageLoopResource(PP_Instance instance); |
34 virtual ~MessageLoopResource(); | 32 virtual ~MessageLoopResource(); |
35 | 33 |
36 // Resource overrides. | 34 // Resource overrides. |
37 virtual PPB_MessageLoop_API* AsPPB_MessageLoop_API() OVERRIDE; | 35 virtual PPB_MessageLoop_API* AsPPB_MessageLoop_API() OVERRIDE; |
38 | 36 |
39 // PPB_MessageLoop_API implementation. | 37 // PPB_MessageLoop_API implementation. |
40 virtual int32_t AttachToCurrentThread() OVERRIDE; | 38 virtual int32_t AttachToCurrentThread() OVERRIDE; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
95 } | 93 } |
96 | 94 |
97 MessageLoopResource::~MessageLoopResource() { | 95 MessageLoopResource::~MessageLoopResource() { |
98 } | 96 } |
99 | 97 |
100 PPB_MessageLoop_API* MessageLoopResource::AsPPB_MessageLoop_API() { | 98 PPB_MessageLoop_API* MessageLoopResource::AsPPB_MessageLoop_API() { |
101 return this; | 99 return this; |
102 } | 100 } |
103 | 101 |
104 int32_t MessageLoopResource::AttachToCurrentThread() { | 102 int32_t MessageLoopResource::AttachToCurrentThread() { |
105 if (tls_slot.initialized()) | 103 PluginGlobals* globals = PluginGlobals::Get(); |
106 return PP_ERROR_INPROGRESS; | 104 |
105 base::ThreadLocalStorage::Slot* slot = globals->msg_loop_slot(); | |
106 if (!slot) { | |
107 slot = new base::ThreadLocalStorage::Slot(&ReleaseMessageLoop); | |
108 globals->set_msg_loop_slot(slot); | |
109 } else { | |
110 if (slot->Get()) | |
111 return PP_ERROR_INPROGRESS; | |
112 } | |
107 // TODO(brettw) check that the current thread can support a message loop. | 113 // TODO(brettw) check that the current thread can support a message loop. |
108 | 114 |
109 // Take a ref to the MessageLoop on behalf of the TLS. Note that this is an | 115 // Take a ref to the MessageLoop on behalf of the TLS. Note that this is an |
110 // internal ref and not a plugin ref so the plugin can't accidentally | 116 // internal ref and not a plugin ref so the plugin can't accidentally |
111 // release it. This is released by ReleaseMessageLoop(). | 117 // release it. This is released by ReleaseMessageLoop(). |
112 AddRef(); | 118 AddRef(); |
113 tls_slot.Initialize(&ReleaseMessageLoop); | 119 slot->Set(this); |
114 tls_slot.Set(this); | |
115 | 120 |
116 loop_.reset(new MessageLoop(MessageLoop::TYPE_DEFAULT)); | 121 loop_.reset(new MessageLoop(MessageLoop::TYPE_DEFAULT)); |
117 | 122 |
118 // Post all pending work to the message loop. | 123 // Post all pending work to the message loop. |
119 for (size_t i = 0; i < pending_tasks_.size(); i++) { | 124 for (size_t i = 0; i < pending_tasks_.size(); i++) { |
120 const TaskInfo& info = pending_tasks_[i]; | 125 const TaskInfo& info = pending_tasks_[i]; |
121 PostClosure(info.from_here, info.closure, info.delay_ms); | 126 PostClosure(info.from_here, info.closure, info.delay_ms); |
122 } | 127 } |
123 pending_tasks_.clear(); | 128 pending_tasks_.clear(); |
124 | 129 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
173 // Note that the message loop must be destroyed on the thread is was created | 178 // Note that the message loop must be destroyed on the thread is was created |
174 // on. | 179 // on. |
175 loop_.reset(); | 180 loop_.reset(); |
176 | 181 |
177 // Cancel out the AddRef in AttachToCurrentThread(). | 182 // Cancel out the AddRef in AttachToCurrentThread(). |
178 Release(); | 183 Release(); |
179 // DANGER: may delete this. | 184 // DANGER: may delete this. |
180 } | 185 } |
181 | 186 |
182 bool MessageLoopResource::IsCurrent() const { | 187 bool MessageLoopResource::IsCurrent() const { |
183 if (!tls_slot.initialized()) | 188 PluginGlobals* globals = PluginGlobals::Get(); |
189 if (!globals->msg_loop_slot()) | |
184 return false; // Can't be current if there's nothing in the slot. | 190 return false; // Can't be current if there's nothing in the slot. |
185 return static_cast<const void*>(tls_slot.Get()) == | 191 return static_cast<const void*>(globals->msg_loop_slot()->Get()) == |
186 static_cast<const void*>(this); | 192 static_cast<const void*>(this); |
187 } | 193 } |
188 | 194 |
189 void MessageLoopResource::PostClosure( | 195 void MessageLoopResource::PostClosure( |
190 const tracked_objects::Location& from_here, | 196 const tracked_objects::Location& from_here, |
191 const base::Closure& closure, | 197 const base::Closure& closure, |
192 int64 delay_ms) { | 198 int64 delay_ms) { |
193 if (loop_.get()) { | 199 if (loop_.get()) { |
194 loop_->PostDelayedTask( | 200 loop_->PostDelayedTask( |
195 from_here, closure, base::TimeDelta::FromMilliseconds(delay_ms)); | 201 from_here, closure, base::TimeDelta::FromMilliseconds(delay_ms)); |
(...skipping 20 matching lines...) Expand all Loading... | |
216 return 0; | 222 return 0; |
217 return (new MessageLoopResource(instance))->GetReference(); | 223 return (new MessageLoopResource(instance))->GetReference(); |
218 } | 224 } |
219 | 225 |
220 PP_Resource GetForMainThread() { | 226 PP_Resource GetForMainThread() { |
221 // TODO(brettw). | 227 // TODO(brettw). |
222 return 0; | 228 return 0; |
223 } | 229 } |
224 | 230 |
225 PP_Resource GetCurrent() { | 231 PP_Resource GetCurrent() { |
226 if (!tls_slot.initialized()) | 232 PluginGlobals* globals = PluginGlobals::Get(); |
233 if (!globals->msg_loop_slot()) | |
227 return 0; | 234 return 0; |
228 MessageLoopResource* loop = reinterpret_cast<MessageLoopResource*>( | 235 MessageLoopResource* loop = reinterpret_cast<MessageLoopResource*>( |
229 tls_slot.Get()); | 236 globals->msg_loop_slot()->Get()); |
230 return loop->GetReference(); | 237 return loop->GetReference(); |
231 } | 238 } |
232 | 239 |
233 int32_t AttachToCurrentThread(PP_Resource message_loop) { | 240 int32_t AttachToCurrentThread(PP_Resource message_loop) { |
234 EnterMessageLoop enter(message_loop, true); | 241 EnterMessageLoop enter(message_loop, true); |
235 if (enter.succeeded()) | 242 if (enter.succeeded()) |
236 return enter.object()->AttachToCurrentThread(); | 243 return enter.object()->AttachToCurrentThread(); |
237 return PP_ERROR_BADRESOURCE; | 244 return PP_ERROR_BADRESOURCE; |
238 } | 245 } |
239 | 246 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
279 PPB_MessageLoop_Proxy::~PPB_MessageLoop_Proxy() { | 286 PPB_MessageLoop_Proxy::~PPB_MessageLoop_Proxy() { |
280 } | 287 } |
281 | 288 |
282 // static | 289 // static |
283 const PPB_MessageLoop_Dev_0_1* PPB_MessageLoop_Proxy::GetInterface() { | 290 const PPB_MessageLoop_Dev_0_1* PPB_MessageLoop_Proxy::GetInterface() { |
284 return &ppb_message_loop_interface; | 291 return &ppb_message_loop_interface; |
285 } | 292 } |
286 | 293 |
287 } // namespace proxy | 294 } // namespace proxy |
288 } // namespace ppapi | 295 } // namespace ppapi |
OLD | NEW |