| Index: content/renderer/pepper/message_channel.cc
|
| diff --git a/content/renderer/pepper/message_channel.cc b/content/renderer/pepper/message_channel.cc
|
| index 1a4e6383b524f9bd4a3b805b14aec4adf8b0d328..959609ff88013435d2574d32c0233afa40ff17a9 100644
|
| --- a/content/renderer/pepper/message_channel.cc
|
| +++ b/content/renderer/pepper/message_channel.cc
|
| @@ -187,6 +187,7 @@ MessageChannel::MessageChannel(PepperPluginInstanceImpl* instance)
|
| plugin_message_queue_state_(WAITING_TO_START),
|
| var_converter_(instance->pp_instance(),
|
| V8VarConverter::kDisallowObjectVars),
|
| + var_conversion_weak_ptr_factory_(this),
|
| weak_ptr_factory_(this) {
|
| }
|
|
|
| @@ -313,26 +314,32 @@ void MessageChannel::PostBlockingMessageToNative(gin::Arguments* args) {
|
| return;
|
| }
|
|
|
| - // If the queue of messages to the plugin is non-empty, we're still waiting on
|
| - // pending Var conversions. This means at some point in the past, JavaScript
|
| - // called postMessage (the async one) and passed us something with a browser-
|
| - // side host (e.g., FileSystem) and we haven't gotten a response from the
|
| - // browser yet. We can't currently support sending a sync message if the
|
| - // plugin does this, because it will break the ordering of the messages
|
| - // arriving at the plugin.
|
| - // TODO(dmichael): Fix this.
|
| - // See https://code.google.com/p/chromium/issues/detail?id=367896#c4
|
| - if (!plugin_message_queue_.empty()) {
|
| - try_catch.ThrowException(
|
| - "Failed to convert parameter synchronously, because a prior "
|
| - "call to postMessage contained a type which required asynchronous "
|
| - "transfer which has not completed. Not all types are supported yet by "
|
| - "postMessageAndAwaitResponse. See crbug.com/367896.");
|
| - return;
|
| - }
|
| ScopedPPVar param = try_catch.FromV8(message_data);
|
| if (try_catch.ThrowException())
|
| return;
|
| + if (!plugin_message_queue_.empty()) {
|
| + // If the queue of messages to the plugin is non-empty, we're still waiting
|
| + // on pending Var conversions. This means at some point in the past,
|
| + // JavaScript called postMessage (the async one) and passed us something
|
| + // with a browser-side host (e.g., FileSystem) and we haven't gotten a
|
| + // response from the browser yet. We have to force all the conversions to
|
| + // happen synchronously so that we can preserve message order.
|
| +
|
| + // CURRENT STRATEGY:
|
| + // 1) Always push async conversions to the browser. They'll be guaranteed
|
| + // to arrive in order.
|
| + // 2) For blocking messages, after you've queued up the conversion, if
|
| + // there's anything waiting in the queue, it's irrelevant whether it
|
| + // is from that sync message or an earlier one. We want to block until
|
| + // it's complete.
|
| +
|
| + // TODO/FIXME Force the browser to convert all pending vars here
|
| + // Mark all messages in the queue completed.
|
| + // Now all our pending vars have completed synchronously, but the browser
|
| + // might already have sent us a response for one or more of them, so we
|
| + // make sure the conversion callbacks don't get invoked.
|
| + var_conversion_weak_ptr_factory_.InvalidateWeakPtrs();
|
| + }
|
|
|
| ScopedPPVar pp_result;
|
| bool was_handled = instance_->HandleBlockingMessage(param, &pp_result);
|
| @@ -398,7 +405,7 @@ void MessageChannel::EnqueuePluginMessage(v8::Handle<v8::Value> v8_value) {
|
| v8_value,
|
| v8::Isolate::GetCurrent()->GetCurrentContext(),
|
| base::Bind(&MessageChannel::FromV8ValueComplete,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| + var_conversion_weak_ptr_factory_.GetWeakPtr(),
|
| &plugin_message_queue_.back()));
|
| if (conversion_result.completed_synchronously) {
|
| plugin_message_queue_.back().ConversionCompleted(
|
|
|