| Index: webkit/plugins/ppapi/message_channel.cc
|
| diff --git a/webkit/plugins/ppapi/message_channel.cc b/webkit/plugins/ppapi/message_channel.cc
|
| index 646b822201ca6e640262c3cd96ee892d2f8a82c3..d63b2844d516366be927f299be634b4fd0dedddc 100644
|
| --- a/webkit/plugins/ppapi/message_channel.cc
|
| +++ b/webkit/plugins/ppapi/message_channel.cc
|
| @@ -24,6 +24,7 @@
|
| #include "v8/include/v8.h"
|
| #include "webkit/plugins/ppapi/host_array_buffer_var.h"
|
| #include "webkit/plugins/ppapi/npapi_glue.h"
|
| +#include "webkit/plugins/ppapi/plugin_module.h"
|
| #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
|
|
|
| using ppapi::ArrayBufferVar;
|
| @@ -330,7 +331,8 @@ MessageChannel::MessageChannel(PluginInstance* instance)
|
| : instance_(instance),
|
| passthrough_object_(NULL),
|
| np_object_(NULL),
|
| - ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
|
| + ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
|
| + early_message_queue_state_(QUEUE_MESSAGES) {
|
| // Now create an NPObject for receiving calls to postMessage. This sets the
|
| // reference count to 1. We release it in the destructor.
|
| NPObject* obj = WebBindings::createObject(NULL, &message_channel_class);
|
| @@ -358,11 +360,57 @@ void MessageChannel::PostMessageToJavaScript(PP_Var message_data) {
|
| WebSerializedScriptValue serialized_val =
|
| WebSerializedScriptValue::serialize(v8_val);
|
|
|
| + if (instance_->module()->IsProxied()) {
|
| + if (early_message_queue_state_ != SEND_DIRECTLY) {
|
| + // We can't just PostTask here; the messages would arrive out of
|
| + // order. Instead, we queue them up until we're ready to post
|
| + // them.
|
| + early_message_queue_.push_back(serialized_val);
|
| + } else {
|
| + // The proxy sent an asynchronous message, so the plugin is already
|
| + // unblocked. Therefore, there's no need to PostTask.
|
| + DCHECK(early_message_queue_.size() == 0);
|
| + PostMessageToJavaScriptImpl(serialized_val);
|
| + }
|
| + } else {
|
| + MessageLoop::current()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&MessageChannel::PostMessageToJavaScriptImpl,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + serialized_val));
|
| + }
|
| +}
|
| +
|
| +void MessageChannel::StopQueueingJavaScriptMessages() {
|
| + // We PostTask here instead of draining the message queue directly
|
| + // since we haven't finished initializing the WebPluginImpl yet, so
|
| + // the plugin isn't available in the DOM.
|
| + early_message_queue_state_ = DRAIN_PENDING;
|
| MessageLoop::current()->PostTask(
|
| FROM_HERE,
|
| - base::Bind(&MessageChannel::PostMessageToJavaScriptImpl,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - serialized_val));
|
| + base::Bind(&MessageChannel::DrainEarlyMessageQueue,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| +}
|
| +
|
| +void MessageChannel::QueueJavaScriptMessages() {
|
| + if (early_message_queue_state_ == DRAIN_PENDING)
|
| + early_message_queue_state_ = DRAIN_CANCELLED;
|
| + else
|
| + early_message_queue_state_ = QUEUE_MESSAGES;
|
| +}
|
| +
|
| +void MessageChannel::DrainEarlyMessageQueue() {
|
| + if (early_message_queue_state_ == DRAIN_CANCELLED) {
|
| + early_message_queue_state_ = QUEUE_MESSAGES;
|
| + return;
|
| + }
|
| + DCHECK(early_message_queue_state_ == DRAIN_PENDING);
|
| +
|
| + while (!early_message_queue_.empty()) {
|
| + PostMessageToJavaScriptImpl(early_message_queue_.front());
|
| + early_message_queue_.pop_front();
|
| + }
|
| + early_message_queue_state_ = SEND_DIRECTLY;
|
| }
|
|
|
| void MessageChannel::PostMessageToJavaScriptImpl(
|
| @@ -398,13 +446,20 @@ void MessageChannel::PostMessageToJavaScriptImpl(
|
| }
|
|
|
| void MessageChannel::PostMessageToNative(PP_Var message_data) {
|
| - // Make a copy of the message data for the Task we will run.
|
| - PP_Var var_copy(CopyPPVar(message_data));
|
| + if (instance_->module()->IsProxied()) {
|
| + // In the proxied case, the copy will happen via serializiation, and the
|
| + // message is asynchronous. Therefore there's no need to copy the Var, nor
|
| + // to PostTask.
|
| + PostMessageToNativeImpl(message_data);
|
| + } else {
|
| + // Make a copy of the message data for the Task we will run.
|
| + PP_Var var_copy(CopyPPVar(message_data));
|
|
|
| - MessageLoop::current()->PostTask(FROM_HERE,
|
| - base::Bind(&MessageChannel::PostMessageToNativeImpl,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - var_copy));
|
| + MessageLoop::current()->PostTask(FROM_HERE,
|
| + base::Bind(&MessageChannel::PostMessageToNativeImpl,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + var_copy));
|
| + }
|
| }
|
|
|
| void MessageChannel::PostMessageToNativeImpl(PP_Var message_data) {
|
|
|