Bug 158239 - Notify client immediately if network session doesn't exist for a synchronous XHR load.
Summary: Notify client immediately if network session doesn't exist for a synchronous ...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit2 (show other bugs)
Version: Other
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2016-05-31 15:15 PDT by Yongjun Zhang
Modified: 2016-06-01 22:38 PDT (History)
6 users (show)

See Also:


Attachments
Notify the client immediately when the network session doesn't exist for a sync XHR request. (2.54 KB, patch)
2016-05-31 15:28 PDT, Yongjun Zhang
no flags Details | Formatted Diff | Diff
Signal the error for all loads. (2.51 KB, patch)
2016-06-01 11:27 PDT, Yongjun Zhang
beidson: review-
Details | Formatted Diff | Diff
V3: notify the client asynchronously. (2.58 KB, patch)
2016-06-01 15:00 PDT, Yongjun Zhang
beidson: review+
Details | Formatted Diff | Diff
Address review comments before landing. (2.57 KB, patch)
2016-06-01 22:07 PDT, Yongjun Zhang
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yongjun Zhang 2016-05-31 15:15:34 PDT
For a synchronous XHR load, if the network session doesn't exist, we should notify NetworkLoadClient immediately. Otherwise the Web process could hang when waiting for the synchronous load to finish.
Comment 1 Yongjun Zhang 2016-05-31 15:16:14 PDT
<rdar://problem/26344251>
Comment 2 Yongjun Zhang 2016-05-31 15:28:11 PDT
Created attachment 280188 [details]
Notify the client immediately when the network session doesn't exist for a sync XHR request.
Comment 3 Brady Eidson 2016-05-31 16:59:14 PDT
Comment on attachment 280188 [details]
Notify the client immediately when the network session doesn't exist for a sync XHR request.

Why is this only an issue for sync loads? It seems like it's an issue for async loads, too.

Sync loads cause a larger issue because the WebProcess is purposefully hanging for them, but isn't it also bad for the WebProcess to think an async load is happening.... forever...? Even though it will never happen?
Comment 4 Yongjun Zhang 2016-05-31 17:24:27 PDT
(In reply to comment #3)
> Comment on attachment 280188 [details]
> Notify the client immediately when the network session doesn't exist for a
> sync XHR request.
> 
> Why is this only an issue for sync loads? It seems like it's an issue for
> async loads, too.
> 
> Sync loads cause a larger issue because the WebProcess is purposefully
> hanging for them, but isn't it also bad for the WebProcess to think an async
> load is happening.... forever...? Even though it will never happen?

I wasn't able to reproduce with async load. We could hit the point where the network session is removed for an async load. However, since this only happens when we closing a web page, Web Process will cancel the load immediately and we won't have a long waiting WebProcess.
Comment 5 Brady Eidson 2016-05-31 18:30:51 PDT
(In reply to comment #4)
> (In reply to comment #3)
> > Comment on attachment 280188 [details]
> > Notify the client immediately when the network session doesn't exist for a
> > sync XHR request.
> > 
> > Why is this only an issue for sync loads? It seems like it's an issue for
> > async loads, too.
> > 
> > Sync loads cause a larger issue because the WebProcess is purposefully
> > hanging for them, but isn't it also bad for the WebProcess to think an async
> > load is happening.... forever...? Even though it will never happen?
> 
> I wasn't able to reproduce with async load. We could hit the point where the
> network session is removed for an async load. However, since this only
> happens when we closing a web page, Web Process will cancel the load
> immediately and we won't have a long waiting WebProcess.

That's *currently* the only time a Session can be removed, but I foresee that could change in the future.

I don't see any downside to immediately signaling the error for all loads.

You've looked at the code more recently - Do you foresee any downside?
Comment 6 Yongjun Zhang 2016-05-31 21:20:05 PDT
(In reply to comment #5)
> (In reply to comment #4)
> > (In reply to comment #3)
> > > Comment on attachment 280188 [details]
> > > Notify the client immediately when the network session doesn't exist for a
> > > sync XHR request.
> > > 
> > > Why is this only an issue for sync loads? It seems like it's an issue for
> > > async loads, too.
> > > 
> > > Sync loads cause a larger issue because the WebProcess is purposefully
> > > hanging for them, but isn't it also bad for the WebProcess to think an async
> > > load is happening.... forever...? Even though it will never happen?
> > 
> > I wasn't able to reproduce with async load. We could hit the point where the
> > network session is removed for an async load. However, since this only
> > happens when we closing a web page, Web Process will cancel the load
> > immediately and we won't have a long waiting WebProcess.
> 
> That's *currently* the only time a Session can be removed, but I foresee
> that could change in the future.
> 
> I don't see any downside to immediately signaling the error for all loads.
> 
> You've looked at the code more recently - Do you foresee any downside?

I don't see any downside either, and I agree signaling the error for all loads sounds more future-proof. I will submit another path. Thanks!
Comment 7 Yongjun Zhang 2016-06-01 11:27:51 PDT
Created attachment 280250 [details]
Signal the error for all loads.
Comment 8 Anders Carlsson 2016-06-01 12:37:38 PDT
Should the callback be made asynchronously, with RunLoop::dispatch or equivalent?
Comment 9 Brady Eidson 2016-06-01 13:31:50 PDT
(In reply to comment #8)
> Should the callback be made asynchronously, with RunLoop::dispatch or
> equivalent?

This was going to be my review feedback. It should be asynchronous.
Comment 10 Brady Eidson 2016-06-01 13:32:59 PDT
Comment on attachment 280250 [details]
Signal the error for all loads.

View in context: https://bugs.webkit.org/attachment.cgi?id=280250&action=review

> Source/WebKit2/NetworkProcess/NetworkLoad.cpp:62
> +        m_client.didFailLoading(internalError(m_currentRequest.url()));

Synchronously calling back to the client - especially in the constructor - is probably inviting trouble.

We should spin the runloop.
Comment 11 Yongjun Zhang 2016-06-01 15:00:52 PDT
Created attachment 280269 [details]
V3: notify the client asynchronously.
Comment 12 Brady Eidson 2016-06-01 17:11:20 PDT
Comment on attachment 280269 [details]
V3: notify the client asynchronously.

View in context: https://bugs.webkit.org/attachment.cgi?id=280269&action=review

> Source/WebKit2/NetworkProcess/NetworkLoad.cpp:64
> +        RunLoop::main().dispatch([this, url = parameters.request.url()] {
> +            didCompleteWithError(internalError(url));
> +        });

This is a super nit pick, and the first time I've ever suggested it...

But we've been looking at all of our lambda usage lately, and going over things like "RunLoop::dispatch" and "callOnMainThread" with a fine toothed comb. We've found a number of thread safety issues.

At a glance, this looks like a potential thread safety issue, because it's unsafe to send a URL across threads without making an isolatedCopy() of it first.

Of course this isn't *actually* a thread safety issue because it's not cross thread - RunLoop::main() happens to also be the current RunLoop.

If the dispatch was instead "RunLoop::current().dispatch(...)", then I wouldn't even have considered it a potential thread safety issue.

If you'd like to make that change, that'd be nice. I haven't thought about it a lot yet, but I think that's what we should do going forward and will likely be discussing with a larger audience soon.

r+ either way.
Comment 13 Yongjun Zhang 2016-06-01 21:53:08 PDT
(In reply to comment #12)
> Comment on attachment 280269 [details]
> V3: notify the client asynchronously.
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=280269&action=review
> 
> > Source/WebKit2/NetworkProcess/NetworkLoad.cpp:64
> > +        RunLoop::main().dispatch([this, url = parameters.request.url()] {
> > +            didCompleteWithError(internalError(url));
> > +        });
> 
> This is a super nit pick, and the first time I've ever suggested it...
> 
> But we've been looking at all of our lambda usage lately, and going over
> things like "RunLoop::dispatch" and "callOnMainThread" with a fine toothed
> comb. We've found a number of thread safety issues.
> 
> At a glance, this looks like a potential thread safety issue, because it's
> unsafe to send a URL across threads without making an isolatedCopy() of it
> first.

Yes, I had the same concern at first, but I convinced myself it won't be an issue - it looks like we expected NetworkLoad to always work on main thread (e.g., we assert this in couple of places). 
> 
> Of course this isn't *actually* a thread safety issue because it's not cross
> thread - RunLoop::main() happens to also be the current RunLoop.
> 
> If the dispatch was instead "RunLoop::current().dispatch(...)", then I
> wouldn't even have considered it a potential thread safety issue.
> 
> If you'd like to make that change, that'd be nice. I haven't thought about
> it a lot yet, but I think that's what we should do going forward and will
> likely be discussing with a larger audience soon.

Sure thing! I will make this change before landing.
> 
> r+ either way.

Thank you for the review!
Comment 14 Yongjun Zhang 2016-06-01 22:07:55 PDT
Created attachment 280307 [details]
Address review comments before landing.
Comment 15 WebKit Commit Bot 2016-06-01 22:38:34 PDT
Comment on attachment 280307 [details]
Address review comments before landing.

Clearing flags on attachment: 280307

Committed r201593: <http://trac.webkit.org/changeset/201593>
Comment 16 WebKit Commit Bot 2016-06-01 22:38:39 PDT
All reviewed patches have been landed.  Closing bug.