Commit 23dc93ca authored by sky@chromium.org's avatar sky@chromium.org

Makes mojo WebUI run main only after page finishes loading

This way there isn't possible race conditions if main is run before
the page finishes loading.

BUG=none
TEST=none
R=darin@chromium.org

Review URL: https://codereview.chromium.org/215373004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@260266 0039d316-1c4b-4281-b951-d872f2087c98
parent efdb7f1a
...@@ -2157,8 +2157,8 @@ void RenderProcessHostImpl::DecrementWorkerRefCount() { ...@@ -2157,8 +2157,8 @@ void RenderProcessHostImpl::DecrementWorkerRefCount() {
#if defined(USE_MOJO) #if defined(USE_MOJO)
void RenderProcessHostImpl::SetWebUIHandle( void RenderProcessHostImpl::SetWebUIHandle(
int32 view_routing_id, int32 view_routing_id,
mojo::ScopedMessagePipeHandle handle) { mojo::ScopedMessagePipeHandle handle) {
if (!render_process_host_mojo_) if (!render_process_host_mojo_)
render_process_host_mojo_.reset(new RenderProcessHostMojoImpl(this)); render_process_host_mojo_.reset(new RenderProcessHostMojoImpl(this));
render_process_host_mojo_->SetWebUIHandle(view_routing_id, handle.Pass()); render_process_host_mojo_->SetWebUIHandle(view_routing_id, handle.Pass());
......
...@@ -15,7 +15,6 @@ namespace content { ...@@ -15,7 +15,6 @@ namespace content {
class MojoChannelInit; class MojoChannelInit;
class RenderProcessHost; class RenderProcessHost;
// RenderProcessHostMojoImpl is responsible for initiating and maintaining the // RenderProcessHostMojoImpl is responsible for initiating and maintaining the
// connection with the content side of RenderProcessHostMojo. // connection with the content side of RenderProcessHostMojo.
class RenderProcessHostMojoImpl : public RenderProcessHostMojo { class RenderProcessHostMojoImpl : public RenderProcessHostMojo {
......
...@@ -41,18 +41,23 @@ void WebUIMojo::MainFrameObserver::WillReleaseScriptContext( ...@@ -41,18 +41,23 @@ void WebUIMojo::MainFrameObserver::WillReleaseScriptContext(
web_ui_mojo_->DestroyContextState(context); web_ui_mojo_->DestroyContextState(context);
} }
void WebUIMojo::MainFrameObserver::DidFinishDocumentLoad() {
web_ui_mojo_->OnDidFinishDocumentLoad();
}
WebUIMojo::WebUIMojo(RenderView* render_view) WebUIMojo::WebUIMojo(RenderView* render_view)
: RenderViewObserver(render_view), : RenderViewObserver(render_view),
RenderViewObserverTracker<WebUIMojo>(render_view), RenderViewObserverTracker<WebUIMojo>(render_view),
main_frame_observer_(this) { main_frame_observer_(this),
did_finish_document_load_(false) {
CreateContextState(); CreateContextState();
} }
void WebUIMojo::SetBrowserHandle(mojo::ScopedMessagePipeHandle handle) { void WebUIMojo::SetBrowserHandle(mojo::ScopedMessagePipeHandle handle) {
v8::HandleScope handle_scope(blink::mainThreadIsolate()); if (did_finish_document_load_)
WebUIMojoContextState* state = GetContextState(); SetHandleOnContextState(handle.Pass());
if (state) else
state->SetHandle(handle.Pass()); pending_handle_ = handle.Pass();
} }
WebUIMojo::~WebUIMojo() { WebUIMojo::~WebUIMojo() {
...@@ -76,6 +81,20 @@ void WebUIMojo::DestroyContextState(v8::Handle<v8::Context> context) { ...@@ -76,6 +81,20 @@ void WebUIMojo::DestroyContextState(v8::Handle<v8::Context> context) {
context_data->RemoveUserData(kWebUIMojoContextStateKey); context_data->RemoveUserData(kWebUIMojoContextStateKey);
} }
void WebUIMojo::OnDidFinishDocumentLoad() {
did_finish_document_load_ = true;
if (pending_handle_.is_valid())
SetHandleOnContextState(pending_handle_.Pass());
}
void WebUIMojo::SetHandleOnContextState(mojo::ScopedMessagePipeHandle handle) {
DCHECK(did_finish_document_load_);
v8::HandleScope handle_scope(blink::mainThreadIsolate());
WebUIMojoContextState* state = GetContextState();
if (state)
state->SetHandle(handle.Pass());
}
WebUIMojoContextState* WebUIMojo::GetContextState() { WebUIMojoContextState* WebUIMojo::GetContextState() {
blink::WebFrame* frame = render_view()->GetWebView()->mainFrame(); blink::WebFrame* frame = render_view()->GetWebView()->mainFrame();
v8::HandleScope handle_scope(blink::mainThreadIsolate()); v8::HandleScope handle_scope(blink::mainThreadIsolate());
......
...@@ -42,6 +42,7 @@ class WebUIMojo ...@@ -42,6 +42,7 @@ class WebUIMojo
// RenderFrameObserver overrides: // RenderFrameObserver overrides:
virtual void WillReleaseScriptContext(v8::Handle<v8::Context> context, virtual void WillReleaseScriptContext(v8::Handle<v8::Context> context,
int world_id) OVERRIDE; int world_id) OVERRIDE;
virtual void DidFinishDocumentLoad() OVERRIDE;
private: private:
WebUIMojo* web_ui_mojo_; WebUIMojo* web_ui_mojo_;
...@@ -54,6 +55,13 @@ class WebUIMojo ...@@ -54,6 +55,13 @@ class WebUIMojo
void CreateContextState(); void CreateContextState();
void DestroyContextState(v8::Handle<v8::Context> context); void DestroyContextState(v8::Handle<v8::Context> context);
// Invoked when the frame finishes loading. Invokes SetHandleOnContextState()
// if necessary.
void OnDidFinishDocumentLoad();
// Invokes SetHandle() on the WebUIMojoContextState (if there is one).
void SetHandleOnContextState(mojo::ScopedMessagePipeHandle handle);
WebUIMojoContextState* GetContextState(); WebUIMojoContextState* GetContextState();
// RenderViewObserver overrides: // RenderViewObserver overrides:
...@@ -62,6 +70,16 @@ class WebUIMojo ...@@ -62,6 +70,16 @@ class WebUIMojo
MainFrameObserver main_frame_observer_; MainFrameObserver main_frame_observer_;
// Set to true in DidFinishDocumentLoad(). 'main' is only executed once this
// happens.
bool did_finish_document_load_;
// If SetBrowserHandle() is invoked before the document finishes loading the
// MessagePipeHandle is stored here. When the document finishes loading
// SetHandleOnContextState() is invoked to send the handle to the
// WebUIMojoContextState and ultimately the page.
mojo::ScopedMessagePipeHandle pending_handle_;
DISALLOW_COPY_AND_ASSIGN(WebUIMojo); DISALLOW_COPY_AND_ASSIGN(WebUIMojo);
}; };
......
...@@ -113,7 +113,7 @@ void WebUIMojoContextState::OnFetchModuleComplete( ...@@ -113,7 +113,7 @@ void WebUIMojoContextState::OnFetchModuleComplete(
DCHECK_EQ(kModulePrefix, DCHECK_EQ(kModulePrefix,
response.url().string().utf8().substr(0, arraysize(kModulePrefix) - 1)); response.url().string().utf8().substr(0, arraysize(kModulePrefix) - 1));
const std::string module = const std::string module =
response.url().string().utf8().substr(arraysize(kModulePrefix)); response.url().string().utf8().substr(arraysize(kModulePrefix) - 1);
// We can't delete fetch right now as the arguments to this function come from // We can't delete fetch right now as the arguments to this function come from
// it and are used below. Instead use a scope_ptr to cleanup. // it and are used below. Instead use a scope_ptr to cleanup.
scoped_ptr<ResourceFetcher> deleter(fetcher); scoped_ptr<ResourceFetcher> deleter(fetcher);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment