Chromium Code Reviews| 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/message_loop.h" | 11 #include "base/location.h" |
| 12 #include "base/message_loop/message_loop_proxy.h" | 12 #include "base/thread_task_runner_handle.h" |
| 13 #include "ppapi/c/pp_errors.h" | 13 #include "ppapi/c/pp_errors.h" |
| 14 #include "ppapi/c/ppb_message_loop.h" | 14 #include "ppapi/c/ppb_message_loop.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 { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 48 // This must be called only once, so the slot must be empty. | 48 // This must be called only once, so the slot must be empty. |
| 49 CHECK(!PluginGlobals::Get()->msg_loop_slot()); | 49 CHECK(!PluginGlobals::Get()->msg_loop_slot()); |
| 50 // We don't add a reference for TLS here, so we don't release it. Instead, | 50 // We don't add a reference for TLS here, so we don't release it. Instead, |
| 51 // this loop is owned by PluginGlobals. Contrast with AttachToCurrentThread | 51 // this loop is owned by PluginGlobals. Contrast with AttachToCurrentThread |
| 52 // where we register ReleaseMessageLoop with TLS and call AddRef. | 52 // where we register ReleaseMessageLoop with TLS and call AddRef. |
| 53 base::ThreadLocalStorage::Slot* slot = new base::ThreadLocalStorage::Slot(); | 53 base::ThreadLocalStorage::Slot* slot = new base::ThreadLocalStorage::Slot(); |
| 54 PluginGlobals::Get()->set_msg_loop_slot(slot); | 54 PluginGlobals::Get()->set_msg_loop_slot(slot); |
| 55 | 55 |
| 56 slot->Set(this); | 56 slot->Set(this); |
| 57 | 57 |
| 58 loop_proxy_ = base::MessageLoopProxy::current(); | 58 task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
| 59 } | 59 } |
| 60 | 60 |
| 61 | 61 |
| 62 MessageLoopResource::~MessageLoopResource() { | 62 MessageLoopResource::~MessageLoopResource() { |
| 63 } | 63 } |
| 64 | 64 |
| 65 PPB_MessageLoop_API* MessageLoopResource::AsPPB_MessageLoop_API() { | 65 PPB_MessageLoop_API* MessageLoopResource::AsPPB_MessageLoop_API() { |
| 66 return this; | 66 return this; |
| 67 } | 67 } |
| 68 | 68 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 82 } | 82 } |
| 83 // TODO(dmichael) 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 base::MessageLoop); | 91 loop_.reset(new base::MessageLoop); |
| 92 loop_proxy_ = base::MessageLoopProxy::current(); | 92 task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
| 93 | 93 |
| 94 // Post all pending work to the message loop. | 94 // Post all pending work to the message loop. |
| 95 for (size_t i = 0; i < pending_tasks_.size(); i++) { | 95 for (size_t i = 0; i < pending_tasks_.size(); i++) { |
| 96 const TaskInfo& info = pending_tasks_[i]; | 96 const TaskInfo& info = pending_tasks_[i]; |
| 97 PostClosure(info.from_here, info.closure, info.delay_ms); | 97 PostClosure(info.from_here, info.closure, info.delay_ms); |
| 98 } | 98 } |
| 99 pending_tasks_.clear(); | 99 pending_tasks_.clear(); |
| 100 | 100 |
| 101 return PP_OK; | 101 return PP_OK; |
| 102 } | 102 } |
| 103 | 103 |
| 104 int32_t MessageLoopResource::Run() { | 104 int32_t MessageLoopResource::Run() { |
| 105 if (!IsCurrent()) | 105 if (!IsCurrent()) |
| 106 return PP_ERROR_WRONG_THREAD; | 106 return PP_ERROR_WRONG_THREAD; |
| 107 if (is_main_thread_loop_) | 107 if (is_main_thread_loop_) |
| 108 return PP_ERROR_INPROGRESS; | 108 return PP_ERROR_INPROGRESS; |
| 109 | 109 |
| 110 nested_invocations_++; | 110 nested_invocations_++; |
| 111 CallWhileUnlocked( | 111 CallWhileUnlocked( |
| 112 base::Bind(&base::MessageLoop::Run, base::Unretained(loop_.get()))); | 112 base::Bind(&base::MessageLoop::Run, base::Unretained(loop_.get()))); |
| 113 nested_invocations_--; | 113 nested_invocations_--; |
| 114 | 114 |
| 115 if (should_destroy_ && nested_invocations_ == 0) { | 115 if (should_destroy_ && nested_invocations_ == 0) { |
| 116 loop_proxy_ = NULL; | 116 task_runner_ = NULL; |
| 117 loop_.reset(); | 117 loop_.reset(); |
| 118 destroyed_ = true; | 118 destroyed_ = true; |
| 119 } | 119 } |
| 120 return PP_OK; | 120 return PP_OK; |
| 121 } | 121 } |
| 122 | 122 |
| 123 int32_t MessageLoopResource::PostWork(PP_CompletionCallback callback, | 123 int32_t MessageLoopResource::PostWork(PP_CompletionCallback callback, |
| 124 int64_t delay_ms) { | 124 int64_t delay_ms) { |
| 125 if (!callback.func) | 125 if (!callback.func) |
| 126 return PP_ERROR_BADARGUMENT; | 126 return PP_ERROR_BADARGUMENT; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 152 PluginGlobals* globals = PluginGlobals::Get(); | 152 PluginGlobals* globals = PluginGlobals::Get(); |
| 153 if (!globals->msg_loop_slot()) | 153 if (!globals->msg_loop_slot()) |
| 154 return NULL; | 154 return NULL; |
| 155 return reinterpret_cast<MessageLoopResource*>( | 155 return reinterpret_cast<MessageLoopResource*>( |
| 156 globals->msg_loop_slot()->Get()); | 156 globals->msg_loop_slot()->Get()); |
| 157 } | 157 } |
| 158 | 158 |
| 159 void MessageLoopResource::DetachFromThread() { | 159 void MessageLoopResource::DetachFromThread() { |
| 160 // Note that the message loop must be destroyed on the thread it was created | 160 // Note that the message loop must be destroyed on the thread it was created |
| 161 // on. | 161 // on. |
| 162 loop_proxy_ = NULL; | 162 task_runner_ = NULL; |
| 163 loop_.reset(); | 163 loop_.reset(); |
| 164 | 164 |
| 165 // Cancel out the AddRef in AttachToCurrentThread(). | 165 // Cancel out the AddRef in AttachToCurrentThread(). |
| 166 Release(); | 166 Release(); |
| 167 // DANGER: may delete this. | 167 // DANGER: may delete this. |
| 168 } | 168 } |
| 169 | 169 |
| 170 bool MessageLoopResource::IsCurrent() const { | 170 bool MessageLoopResource::IsCurrent() const { |
| 171 PluginGlobals* globals = PluginGlobals::Get(); | 171 PluginGlobals* globals = PluginGlobals::Get(); |
| 172 if (!globals->msg_loop_slot()) | 172 if (!globals->msg_loop_slot()) |
| 173 return false; // Can't be current if there's nothing in the slot. | 173 return false; // Can't be current if there's nothing in the slot. |
| 174 return static_cast<const void*>(globals->msg_loop_slot()->Get()) == | 174 return static_cast<const void*>(globals->msg_loop_slot()->Get()) == |
| 175 static_cast<const void*>(this); | 175 static_cast<const void*>(this); |
| 176 } | 176 } |
| 177 | 177 |
| 178 void MessageLoopResource::PostClosure( | 178 void MessageLoopResource::PostClosure( |
| 179 const tracked_objects::Location& from_here, | 179 const tracked_objects::Location& from_here, |
| 180 const base::Closure& closure, | 180 const base::Closure& closure, |
| 181 int64 delay_ms) { | 181 int64 delay_ms) { |
| 182 if (loop_proxy_.get()) { | 182 if (task_runner_.get()) { |
| 183 loop_proxy_->PostDelayedTask( | 183 task_runner_->PostDelayedTask(from_here, closure, |
| 184 from_here, closure, base::TimeDelta::FromMilliseconds(delay_ms)); | 184 base::TimeDelta::FromMilliseconds(delay_ms)); |
| 185 } else { | 185 } else { |
| 186 TaskInfo info; | 186 TaskInfo info; |
| 187 info.from_here = FROM_HERE; | 187 info.from_here = FROM_HERE; |
| 188 info.closure = closure; | 188 info.closure = closure; |
| 189 info.delay_ms = delay_ms; | 189 info.delay_ms = delay_ms; |
| 190 pending_tasks_.push_back(info); | 190 pending_tasks_.push_back(info); |
| 191 } | 191 } |
| 192 } | 192 } |
| 193 | 193 |
| 194 base::MessageLoopProxy* MessageLoopResource::GetMessageLoopProxy() { | 194 base::SingleThreadTaskRunner* MessageLoopResource::GetMessageLoopProxy() { |
|
bbudge
2015/06/10 20:57:46
Name 'GetMessageLoopProxy' is now misleading.
Sami
2015/06/11 18:03:46
Done.
| |
| 195 return loop_proxy_.get(); | 195 return task_runner_.get(); |
| 196 } | 196 } |
| 197 | 197 |
| 198 bool MessageLoopResource::CurrentlyHandlingBlockingMessage() { | 198 bool MessageLoopResource::CurrentlyHandlingBlockingMessage() { |
| 199 return currently_handling_blocking_message_; | 199 return currently_handling_blocking_message_; |
| 200 } | 200 } |
| 201 | 201 |
| 202 // static | 202 // static |
| 203 void MessageLoopResource::ReleaseMessageLoop(void* value) { | 203 void MessageLoopResource::ReleaseMessageLoop(void* value) { |
| 204 static_cast<MessageLoopResource*>(value)->DetachFromThread(); | 204 static_cast<MessageLoopResource*>(value)->DetachFromThread(); |
| 205 } | 205 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 275 PPB_MessageLoop_Proxy::~PPB_MessageLoop_Proxy() { | 275 PPB_MessageLoop_Proxy::~PPB_MessageLoop_Proxy() { |
| 276 } | 276 } |
| 277 | 277 |
| 278 // static | 278 // static |
| 279 const PPB_MessageLoop_1_0* PPB_MessageLoop_Proxy::GetInterface() { | 279 const PPB_MessageLoop_1_0* PPB_MessageLoop_Proxy::GetInterface() { |
| 280 return &ppb_message_loop_interface; | 280 return &ppb_message_loop_interface; |
| 281 } | 281 } |
| 282 | 282 |
| 283 } // namespace proxy | 283 } // namespace proxy |
| 284 } // namespace ppapi | 284 } // namespace ppapi |
| OLD | NEW |