15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppb_message_loop_proxy.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/ppb_message_loop.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/plugin_dispatcher.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/plugin_globals.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/proxy_lock.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/enter.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::thunk::PPB_MessageLoop_API; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace proxy { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef thunk::EnterResource<PPB_MessageLoop_API> EnterMessageLoop; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageLoopResource::MessageLoopResource(PP_Instance instance) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : MessageLoopShared(instance), 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_invocations_(0), 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destroyed_(false), 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) should_destroy_(false), 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_main_thread_loop_(false), 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci currently_handling_blocking_message_(false) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageLoopResource::MessageLoopResource(ForMainThread for_main_thread) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : MessageLoopShared(for_main_thread), 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_invocations_(0), 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destroyed_(false), 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) should_destroy_(false), 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_main_thread_loop_(true), 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci currently_handling_blocking_message_(false) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We attach the main thread immediately. We can't use AttachToCurrentThread, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because the MessageLoop already exists. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This must be called only once, so the slot must be empty. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!PluginGlobals::Get()->msg_loop_slot()); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We don't add a reference for TLS here, so we don't release it. Instead, 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // this loop is owned by PluginGlobals. Contrast with AttachToCurrentThread 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // where we register ReleaseMessageLoop with TLS and call AddRef. 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ThreadLocalStorage::Slot* slot = new base::ThreadLocalStorage::Slot(); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PluginGlobals::Get()->set_msg_loop_slot(slot); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slot->Set(this); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_proxy_ = base::MessageLoopProxy::current(); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageLoopResource::~MessageLoopResource() { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_MessageLoop_API* MessageLoopResource::AsPPB_MessageLoop_API() { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t MessageLoopResource::AttachToCurrentThread() { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_main_thread_loop_) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_ERROR_INPROGRESS; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PluginGlobals* globals = PluginGlobals::Get(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadLocalStorage::Slot* slot = globals->msg_loop_slot(); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!slot) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slot = new base::ThreadLocalStorage::Slot(&ReleaseMessageLoop); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) globals->set_msg_loop_slot(slot); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (slot->Get()) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_ERROR_INPROGRESS; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(dmichael) check that the current thread can support a message loop. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Take a ref to the MessageLoop on behalf of the TLS. Note that this is an 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // internal ref and not a plugin ref so the plugin can't accidentally 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // release it. This is released by ReleaseMessageLoop(). 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRef(); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) slot->Set(this); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) loop_.reset(new base::MessageLoop); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_proxy_ = base::MessageLoopProxy::current(); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Post all pending work to the message loop. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < pending_tasks_.size(); i++) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TaskInfo& info = pending_tasks_[i]; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostClosure(info.from_here, info.closure, info.delay_ms); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_tasks_.clear(); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_OK; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t MessageLoopResource::Run() { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsCurrent()) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_ERROR_WRONG_THREAD; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_main_thread_loop_) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_ERROR_INPROGRESS; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_invocations_++; 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CallWhileUnlocked( 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&base::MessageLoop::Run, base::Unretained(loop_.get()))); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_invocations_--; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (should_destroy_ && nested_invocations_ == 0) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_proxy_ = NULL; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_.reset(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destroyed_ = true; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_OK; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t MessageLoopResource::PostWork(PP_CompletionCallback callback, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64_t delay_ms) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!callback.func) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (destroyed_) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_ERROR_FAILED; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostClosure(FROM_HERE, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(callback.func, callback.user_data, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int32_t>(PP_OK)), 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay_ms); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_OK; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t MessageLoopResource::PostQuit(PP_Bool should_destroy) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_main_thread_loop_) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_ERROR_WRONG_THREAD; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PP_ToBool(should_destroy)) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) should_destroy_ = true; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsCurrent() && nested_invocations_ > 0) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_->Quit(); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PostClosure(FROM_HERE, base::MessageLoop::QuitClosure(), 0); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_OK; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageLoopResource* MessageLoopResource::GetCurrent() { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PluginGlobals* globals = PluginGlobals::Get(); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!globals->msg_loop_slot()) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<MessageLoopResource*>( 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) globals->msg_loop_slot()->Get()); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoopResource::DetachFromThread() { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that the message loop must be destroyed on the thread it was created 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_proxy_ = NULL; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loop_.reset(); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel out the AddRef in AttachToCurrentThread(). 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DANGER: may delete this. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MessageLoopResource::IsCurrent() const { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PluginGlobals* globals = PluginGlobals::Get(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!globals->msg_loop_slot()) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // Can't be current if there's nothing in the slot. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<const void*>(globals->msg_loop_slot()->Get()) == 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<const void*>(this); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoopResource::PostClosure( 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& closure, 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 delay_ms) { 182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (loop_proxy_.get()) { 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) loop_proxy_->PostDelayedTask( 184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) from_here, closure, base::TimeDelta::FromMilliseconds(delay_ms)); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TaskInfo info; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.from_here = FROM_HERE; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.closure = closure; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.delay_ms = delay_ms; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_tasks_.push_back(info); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::MessageLoopProxy* MessageLoopResource::GetMessageLoopProxy() { 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return loop_proxy_.get(); 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool MessageLoopResource::CurrentlyHandlingBlockingMessage() { 1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return currently_handling_blocking_message_; 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageLoopResource::ReleaseMessageLoop(void* value) { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<MessageLoopResource*>(value)->DetachFromThread(); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ----------------------------------------------------------------------------- 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Resource Create(PP_Instance instance) { 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyAutoLock lock; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Validate the instance. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!dispatcher) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (new MessageLoopResource(instance))->GetReference(); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Resource GetForMainThread() { 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyAutoLock lock; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PluginGlobals::Get()->loop_for_main_thread()->GetReference(); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Resource GetCurrent() { 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyAutoLock lock; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Resource* resource = MessageLoopResource::GetCurrent(); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (resource) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return resource->GetReference(); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t AttachToCurrentThread(PP_Resource message_loop) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnterMessageLoop enter(message_loop, true); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enter.succeeded()) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return enter.object()->AttachToCurrentThread(); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_ERROR_BADRESOURCE; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t Run(PP_Resource message_loop) { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnterMessageLoop enter(message_loop, true); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enter.succeeded()) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return enter.object()->Run(); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_ERROR_BADRESOURCE; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t PostWork(PP_Resource message_loop, 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_CompletionCallback callback, 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64_t delay_ms) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnterMessageLoop enter(message_loop, true); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enter.succeeded()) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return enter.object()->PostWork(callback, delay_ms); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_ERROR_BADRESOURCE; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t PostQuit(PP_Resource message_loop, PP_Bool should_destroy) { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnterMessageLoop enter(message_loop, true); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enter.succeeded()) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return enter.object()->PostQuit(should_destroy); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_ERROR_BADRESOURCE; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const PPB_MessageLoop_1_0 ppb_message_loop_interface = { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Create, 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetForMainThread, 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetCurrent, 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AttachToCurrentThread, 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Run, 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &PostWork, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &PostQuit 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_MessageLoop_Proxy::PPB_MessageLoop_Proxy(Dispatcher* dispatcher) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : InterfaceProxy(dispatcher) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_MessageLoop_Proxy::~PPB_MessageLoop_Proxy() { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const PPB_MessageLoop_1_0* PPB_MessageLoop_Proxy::GetInterface() { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &ppb_message_loop_interface; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace proxy 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ppapi 285