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

Side by Side Diff: ppapi/proxy/ppb_message_loop_proxy.cc

Issue 10910099: PPAPI: Make CompletionCallbacks work right on background threads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge Created 8 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « ppapi/proxy/ppb_message_loop_proxy.h ('k') | ppapi/proxy/ppb_testing_proxy.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/message_loop_proxy.h" 12 #include "base/message_loop_proxy.h"
13 #include "ppapi/c/dev/ppb_message_loop_dev.h" 13 #include "ppapi/c/dev/ppb_message_loop_dev.h"
14 #include "ppapi/c/pp_errors.h" 14 #include "ppapi/c/pp_errors.h"
15 #include "ppapi/proxy/plugin_dispatcher.h" 15 #include "ppapi/proxy/plugin_dispatcher.h"
16 #include "ppapi/proxy/plugin_globals.h" 16 #include "ppapi/proxy/plugin_globals.h"
17 #include "ppapi/shared_impl/proxy_lock.h" 17 #include "ppapi/shared_impl/proxy_lock.h"
18 #include "ppapi/thunk/enter.h" 18 #include "ppapi/thunk/enter.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 typedef thunk::EnterResource<PPB_MessageLoop_API> EnterMessageLoop; 26 typedef thunk::EnterResource<PPB_MessageLoop_API> EnterMessageLoop;
27 } 27 }
28 28
29 MessageLoopResource::MessageLoopResource(PP_Instance instance) 29 MessageLoopResource::MessageLoopResource(PP_Instance instance)
30 : Resource(OBJECT_IS_PROXY, instance), 30 : MessageLoopShared(instance),
31 nested_invocations_(0), 31 nested_invocations_(0),
32 destroyed_(false), 32 destroyed_(false),
33 should_destroy_(false), 33 should_destroy_(false),
34 is_main_thread_loop_(false) { 34 is_main_thread_loop_(false) {
35 } 35 }
36 36
37 MessageLoopResource::MessageLoopResource(ForMainThread) 37 MessageLoopResource::MessageLoopResource(ForMainThread for_main_thread)
38 : Resource(Resource::Untracked()), 38 : MessageLoopShared(for_main_thread),
39 nested_invocations_(0), 39 nested_invocations_(0),
40 destroyed_(false), 40 destroyed_(false),
41 should_destroy_(false), 41 should_destroy_(false),
42 is_main_thread_loop_(true) { 42 is_main_thread_loop_(true) {
43 // We attach the main thread immediately. We can't use AttachToCurrentThread, 43 // We attach the main thread immediately. We can't use AttachToCurrentThread,
44 // because the MessageLoop already exists. 44 // because the MessageLoop already exists.
45 45
46 // This must be called only once, so the slot must be empty. 46 // This must be called only once, so the slot must be empty.
47 CHECK(!PluginGlobals::Get()->msg_loop_slot()); 47 CHECK(!PluginGlobals::Get()->msg_loop_slot());
48 base::ThreadLocalStorage::Slot* slot = 48 base::ThreadLocalStorage::Slot* slot =
(...skipping 24 matching lines...) Expand all
73 PluginGlobals* globals = PluginGlobals::Get(); 73 PluginGlobals* globals = PluginGlobals::Get();
74 74
75 base::ThreadLocalStorage::Slot* slot = globals->msg_loop_slot(); 75 base::ThreadLocalStorage::Slot* slot = globals->msg_loop_slot();
76 if (!slot) { 76 if (!slot) {
77 slot = new base::ThreadLocalStorage::Slot(&ReleaseMessageLoop); 77 slot = new base::ThreadLocalStorage::Slot(&ReleaseMessageLoop);
78 globals->set_msg_loop_slot(slot); 78 globals->set_msg_loop_slot(slot);
79 } else { 79 } else {
80 if (slot->Get()) 80 if (slot->Get())
81 return PP_ERROR_INPROGRESS; 81 return PP_ERROR_INPROGRESS;
82 } 82 }
83 // TODO(brettw) check that the current thread can support a message loop. 83 // TODO(dmichael) check that the current thread can support a message loop.
84 84
85 // Take a ref to the MessageLoop on behalf of the TLS. Note that this is an 85 // Take a ref to the MessageLoop on behalf of the TLS. Note that this is an
86 // internal ref and not a plugin ref so the plugin can't accidentally 86 // internal ref and not a plugin ref so the plugin can't accidentally
87 // release it. This is released by ReleaseMessageLoop(). 87 // release it. This is released by ReleaseMessageLoop().
88 AddRef(); 88 AddRef();
89 slot->Set(this); 89 slot->Set(this);
90 90
91 loop_.reset(new MessageLoop(MessageLoop::TYPE_DEFAULT)); 91 loop_.reset(new MessageLoop(MessageLoop::TYPE_DEFAULT));
92 loop_proxy_ = base::MessageLoopProxy::current(); 92 loop_proxy_ = base::MessageLoopProxy::current();
93 93
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 return PP_OK; 133 return PP_OK;
134 } 134 }
135 135
136 int32_t MessageLoopResource::PostQuit(PP_Bool should_destroy) { 136 int32_t MessageLoopResource::PostQuit(PP_Bool should_destroy) {
137 if (is_main_thread_loop_) 137 if (is_main_thread_loop_)
138 return PP_ERROR_WRONG_THREAD; 138 return PP_ERROR_WRONG_THREAD;
139 139
140 if (PP_ToBool(should_destroy)) 140 if (PP_ToBool(should_destroy))
141 should_destroy_ = true; 141 should_destroy_ = true;
142 142
143 if (IsCurrent()) 143 if (IsCurrent() && nested_invocations_ > 0)
144 loop_->Quit(); 144 loop_->Quit();
145 else 145 else
146 PostClosure(FROM_HERE, MessageLoop::QuitClosure(), 0); 146 PostClosure(FROM_HERE, MessageLoop::QuitClosure(), 0);
147 return PP_OK; 147 return PP_OK;
148 } 148 }
149 149
150 // static
151 MessageLoopResource* MessageLoopResource::GetCurrent() {
152 PluginGlobals* globals = PluginGlobals::Get();
153 if (!globals->msg_loop_slot())
154 return NULL;
155 return reinterpret_cast<MessageLoopResource*>(
156 globals->msg_loop_slot()->Get());
157 }
158
150 void MessageLoopResource::DetachFromThread() { 159 void MessageLoopResource::DetachFromThread() {
151 // Never detach the main thread from its loop resource. Other plugin instances 160 // Note that the message loop must be destroyed on the thread it was created
152 // might need it.
153 if (is_main_thread_loop_)
154 return;
155
156 // Note that the message loop must be destroyed on the thread is was created
157 // on. 161 // on.
158 loop_proxy_ = NULL; 162 loop_proxy_ = NULL;
159 loop_.reset(); 163 loop_.reset();
160 164
161 // Cancel out the AddRef in AttachToCurrentThread(). 165 // Cancel out the AddRef in AttachToCurrentThread().
162 Release(); 166 Release();
163 // DANGER: may delete this. 167 // DANGER: may delete this.
164 } 168 }
165 169
166 bool MessageLoopResource::IsCurrent() const { 170 bool MessageLoopResource::IsCurrent() const {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 if (!dispatcher) 205 if (!dispatcher)
202 return 0; 206 return 0;
203 return (new MessageLoopResource(instance))->GetReference(); 207 return (new MessageLoopResource(instance))->GetReference();
204 } 208 }
205 209
206 PP_Resource GetForMainThread() { 210 PP_Resource GetForMainThread() {
207 return PluginGlobals::Get()->loop_for_main_thread()->GetReference(); 211 return PluginGlobals::Get()->loop_for_main_thread()->GetReference();
208 } 212 }
209 213
210 PP_Resource GetCurrent() { 214 PP_Resource GetCurrent() {
211 PluginGlobals* globals = PluginGlobals::Get(); 215 Resource* resource = MessageLoopResource::GetCurrent();
212 if (!globals->msg_loop_slot()) 216 if (resource)
213 return 0; 217 return resource->GetReference();
214 MessageLoopResource* loop = reinterpret_cast<MessageLoopResource*>( 218 return 0;
215 globals->msg_loop_slot()->Get());
216 return loop->GetReference();
217 } 219 }
218 220
219 int32_t AttachToCurrentThread(PP_Resource message_loop) { 221 int32_t AttachToCurrentThread(PP_Resource message_loop) {
220 EnterMessageLoop enter(message_loop, true); 222 EnterMessageLoop enter(message_loop, true);
221 if (enter.succeeded()) 223 if (enter.succeeded())
222 return enter.object()->AttachToCurrentThread(); 224 return enter.object()->AttachToCurrentThread();
223 return PP_ERROR_BADRESOURCE; 225 return PP_ERROR_BADRESOURCE;
224 } 226 }
225 227
226 int32_t Run(PP_Resource message_loop) { 228 int32_t Run(PP_Resource message_loop) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 PPB_MessageLoop_Proxy::~PPB_MessageLoop_Proxy() { 265 PPB_MessageLoop_Proxy::~PPB_MessageLoop_Proxy() {
264 } 266 }
265 267
266 // static 268 // static
267 const PPB_MessageLoop_Dev_0_1* PPB_MessageLoop_Proxy::GetInterface() { 269 const PPB_MessageLoop_Dev_0_1* PPB_MessageLoop_Proxy::GetInterface() {
268 return &ppb_message_loop_interface; 270 return &ppb_message_loop_interface;
269 } 271 }
270 272
271 } // namespace proxy 273 } // namespace proxy
272 } // namespace ppapi 274 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/proxy/ppb_message_loop_proxy.h ('k') | ppapi/proxy/ppb_testing_proxy.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698