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

Unified Diff: ppapi/proxy/ppb_message_loop_proxy.cc

Issue 10790078: PPAPI: Make PPB_MessageLoop_Dev::GetForMainThread work (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: review comments Created 8 years, 4 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ppapi/proxy/ppb_message_loop_proxy.h ('k') | ppapi/shared_impl/resource.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ppapi/proxy/ppb_message_loop_proxy.cc
diff --git a/ppapi/proxy/ppb_message_loop_proxy.cc b/ppapi/proxy/ppb_message_loop_proxy.cc
index bcbb82a72a940e6086c450f695104a07f01840a2..916002d0795981d4be027dc4b2034ea080c33044 100644
--- a/ppapi/proxy/ppb_message_loop_proxy.cc
+++ b/ppapi/proxy/ppb_message_loop_proxy.cc
@@ -9,14 +9,13 @@
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/message_loop.h"
+#include "base/message_loop_proxy.h"
#include "ppapi/c/dev/ppb_message_loop_dev.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/plugin_globals.h"
#include "ppapi/shared_impl/proxy_lock.h"
-#include "ppapi/shared_impl/resource.h"
#include "ppapi/thunk/enter.h"
-#include "ppapi/thunk/ppb_message_loop_api.h"
using ppapi::thunk::PPB_MessageLoop_API;
@@ -24,78 +23,42 @@ namespace ppapi {
namespace proxy {
namespace {
-
typedef thunk::EnterResource<PPB_MessageLoop_API> EnterMessageLoop;
-
-class MessageLoopResource : public Resource, public PPB_MessageLoop_API {
- public:
- MessageLoopResource(PP_Instance instance);
- virtual ~MessageLoopResource();
-
- // Resource overrides.
- virtual PPB_MessageLoop_API* AsPPB_MessageLoop_API() OVERRIDE;
-
- // PPB_MessageLoop_API implementation.
- virtual int32_t AttachToCurrentThread() OVERRIDE;
- virtual int32_t Run() OVERRIDE;
- virtual int32_t PostWork(PP_CompletionCallback callback,
- int64_t delay_ms) OVERRIDE;
- virtual int32_t PostQuit(PP_Bool should_destroy) OVERRIDE;
-
- void DetachFromThread();
-
- private:
- struct TaskInfo {
- tracked_objects::Location from_here;
- base::Closure closure;
- int64 delay_ms;
- };
-
- // Returns true if the object is associated with the current thread.
- bool IsCurrent() const;
-
- // Handles posting to the message loop if there is one, or the pending queue
- // if there isn't.
- // NOTE: The given closure will be run *WITHOUT* acquiring the Proxy lock.
- // This only makes sense for user code and completely thread-safe
- // proxy operations (e.g., MessageLoop::QuitClosure).
- void PostClosure(const tracked_objects::Location& from_here,
- const base::Closure& closure,
- int64 delay_ms);
-
- // TLS destructor function.
- static void ReleaseMessageLoop(void* value);
-
- // Created when we attach to the current thread, since MessageLoop assumes
- // that it's created on the thread it will run on.
- scoped_ptr<MessageLoop> loop_;
-
- // Number of invocations of Run currently on the stack.
- int nested_invocations_;
-
- // Set to true when the message loop is destroyed to prevent forther
- // posting of work.
- bool destroyed_;
-
- // Set to true if all message loop invocations should exit and that the
- // loop should be destroyed once it reaches the outermost Run invocation.
- bool should_destroy_;
-
- // Since we allow tasks to be posted before the message loop is actually
- // created (when it's associated with a thread), we keep tasks posted here
- // until that happens. Once the loop_ is created, this is unused.
- std::vector<TaskInfo> pending_tasks_;
-
- DISALLOW_COPY_AND_ASSIGN(MessageLoopResource);
-};
+}
MessageLoopResource::MessageLoopResource(PP_Instance instance)
: Resource(OBJECT_IS_PROXY, instance),
nested_invocations_(0),
destroyed_(false),
- should_destroy_(false) {
+ should_destroy_(false),
+ is_main_thread_loop_(false) {
+}
+
+MessageLoopResource::MessageLoopResource(ForMainThread)
+ : Resource(Resource::Untracked()),
+ nested_invocations_(0),
+ destroyed_(false),
+ should_destroy_(false),
+ is_main_thread_loop_(true) {
+ // We attach the main thread immediately. We can't use AttachToCurrentThread,
+ // because the MessageLoop already exists.
+
+ // This must be called only once, so the slot must be empty.
+ CHECK(!PluginGlobals::Get()->msg_loop_slot());
+ base::ThreadLocalStorage::Slot* slot =
+ new base::ThreadLocalStorage::Slot(&ReleaseMessageLoop);
+ PluginGlobals::Get()->set_msg_loop_slot(slot);
+
+ // Take a ref to the MessageLoop on behalf of the TLS. Note that this is an
+ // internal ref and not a plugin ref so the plugin can't accidentally
+ // release it. This is released by ReleaseMessageLoop().
+ AddRef();
+ slot->Set(this);
+
+ loop_proxy_ = base::MessageLoopProxy::current();
}
+
MessageLoopResource::~MessageLoopResource() {
}
@@ -104,6 +67,9 @@ PPB_MessageLoop_API* MessageLoopResource::AsPPB_MessageLoop_API() {
}
int32_t MessageLoopResource::AttachToCurrentThread() {
+ if (is_main_thread_loop_)
+ return PP_ERROR_INPROGRESS;
+
PluginGlobals* globals = PluginGlobals::Get();
base::ThreadLocalStorage::Slot* slot = globals->msg_loop_slot();
@@ -123,6 +89,7 @@ int32_t MessageLoopResource::AttachToCurrentThread() {
slot->Set(this);
loop_.reset(new MessageLoop(MessageLoop::TYPE_DEFAULT));
+ loop_proxy_ = base::MessageLoopProxy::current();
// Post all pending work to the message loop.
for (size_t i = 0; i < pending_tasks_.size(); i++) {
@@ -137,9 +104,8 @@ int32_t MessageLoopResource::AttachToCurrentThread() {
int32_t MessageLoopResource::Run() {
if (!IsCurrent())
return PP_ERROR_WRONG_THREAD;
- // TODO(brettw) prevent this from happening on the main thread & return
- // PP_ERROR_BLOCKS_MAIN_THREAD. Maybe have a special constructor for that
- // one?
+ if (is_main_thread_loop_)
+ return PP_ERROR_INPROGRESS;
nested_invocations_++;
CallWhileUnlocked(base::Bind(&MessageLoop::Run,
@@ -147,6 +113,7 @@ int32_t MessageLoopResource::Run() {
nested_invocations_--;
if (should_destroy_ && nested_invocations_ == 0) {
+ loop_proxy_ = NULL;
loop_.reset();
destroyed_ = true;
}
@@ -167,6 +134,9 @@ int32_t MessageLoopResource::PostWork(PP_CompletionCallback callback,
}
int32_t MessageLoopResource::PostQuit(PP_Bool should_destroy) {
+ if (is_main_thread_loop_)
+ return PP_ERROR_WRONG_THREAD;
+
if (PP_ToBool(should_destroy))
should_destroy_ = true;
@@ -178,8 +148,14 @@ int32_t MessageLoopResource::PostQuit(PP_Bool should_destroy) {
}
void MessageLoopResource::DetachFromThread() {
+ // Never detach the main thread from its loop resource. Other plugin instances
+ // might need it.
+ if (is_main_thread_loop_)
+ return;
+
// Note that the message loop must be destroyed on the thread is was created
// on.
+ loop_proxy_ = NULL;
loop_.reset();
// Cancel out the AddRef in AttachToCurrentThread().
@@ -199,10 +175,10 @@ void MessageLoopResource::PostClosure(
const tracked_objects::Location& from_here,
const base::Closure& closure,
int64 delay_ms) {
- if (loop_.get()) {
- loop_->PostDelayedTask(from_here,
- closure,
- base::TimeDelta::FromMilliseconds(delay_ms));
+ if (loop_proxy_) {
+ loop_proxy_->PostDelayedTask(from_here,
+ closure,
+ base::TimeDelta::FromMilliseconds(delay_ms));
} else {
TaskInfo info;
info.from_here = FROM_HERE;
@@ -228,8 +204,7 @@ PP_Resource Create(PP_Instance instance) {
}
PP_Resource GetForMainThread() {
- // TODO(brettw).
- return 0;
+ return PluginGlobals::Get()->loop_for_main_thread()->GetReference();
}
PP_Resource GetCurrent() {
@@ -281,8 +256,6 @@ const PPB_MessageLoop_Dev_0_1 ppb_message_loop_interface = {
&PostQuit
};
-} // namespace
-
PPB_MessageLoop_Proxy::PPB_MessageLoop_Proxy(Dispatcher* dispatcher)
: InterfaceProxy(dispatcher) {
}
« no previous file with comments | « ppapi/proxy/ppb_message_loop_proxy.h ('k') | ppapi/shared_impl/resource.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698