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)#ifndef PPAPI_PROXY_PPB_MESSAGE_LOOP_PROXY_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_PROXY_PPB_MESSAGE_LOOP_PROXY_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/interface_proxy.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/ppapi_proxy_export.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/ppb_message_loop_shared.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/ppb_message_loop_api.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct PPB_MessageLoop_1_0; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace proxy { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PPAPI_PROXY_EXPORT MessageLoopResource : public MessageLoopShared { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit MessageLoopResource(PP_Instance instance); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct the one MessageLoopResource for the main thread. This must be 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // invoked on the main thread. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit MessageLoopResource(ForMainThread); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~MessageLoopResource(); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Resource overrides. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual thunk::PPB_MessageLoop_API* AsPPB_MessageLoop_API() OVERRIDE; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // PPB_MessageLoop_API implementation. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int32_t AttachToCurrentThread() OVERRIDE; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int32_t Run() OVERRIDE; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int32_t PostWork(PP_CompletionCallback callback, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64_t delay_ms) OVERRIDE; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int32_t PostQuit(PP_Bool should_destroy) OVERRIDE; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static MessageLoopResource* GetCurrent(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DetachFromThread(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_main_thread_loop() const { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return is_main_thread_loop_; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy() { 48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return loop_proxy_; 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void set_currently_handling_blocking_message(bool handling_blocking_message) { 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci currently_handling_blocking_message_ = handling_blocking_message; 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct TaskInfo { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tracked_objects::Location from_here; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Closure closure; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 delay_ms; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the object is associated with the current thread. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsCurrent() const; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // MessageLoopShared implementation. 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handles posting to the message loop if there is one, or the pending queue 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if there isn't. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: The given closure will be run *WITHOUT* acquiring the Proxy lock. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This only makes sense for user code and completely thread-safe 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // proxy operations (e.g., MessageLoop::QuitClosure). 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void PostClosure(const tracked_objects::Location& from_here, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& closure, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 delay_ms) OVERRIDE; 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual base::MessageLoopProxy* GetMessageLoopProxy() OVERRIDE; 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual bool CurrentlyHandlingBlockingMessage() OVERRIDE; 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TLS destructor function. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void ReleaseMessageLoop(void* value); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Created when we attach to the current thread, since MessageLoop assumes 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that it's created on the thread it will run on. NULL for the main thread 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // loop, since that's owned by somebody else. This is needed for Run and Quit. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Any time we post tasks, we should post them using loop_proxy_. 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::MessageLoop> loop_; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> loop_proxy_; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Number of invocations of Run currently on the stack. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nested_invocations_; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set to true when the message loop is destroyed to prevent forther 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // posting of work. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool destroyed_; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set to true if all message loop invocations should exit and that the 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // loop should be destroyed once it reaches the outermost Run invocation. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool should_destroy_; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_main_thread_loop_; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool currently_handling_blocking_message_; 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since we allow tasks to be posted before the message loop is actually 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // created (when it's associated with a thread), we keep tasks posted here 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // until that happens. Once the loop_ is created, this is unused. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<TaskInfo> pending_tasks_; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MessageLoopResource); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PPB_MessageLoop_Proxy : public InterfaceProxy { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit PPB_MessageLoop_Proxy(Dispatcher* dispatcher); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~PPB_MessageLoop_Proxy(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const PPB_MessageLoop_1_0* GetInterface(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PPB_MessageLoop_Proxy); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace proxy 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ppapi 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // PPAPI_PROXY_PPB_MESSAGE_LOOP_PROXY_H_ 126