WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
174270
NetworkProcess should close listening WebRTC sockets when being suspended
https://bugs.webkit.org/show_bug.cgi?id=174270
Summary
NetworkProcess should close listening WebRTC sockets when being suspended
youenn fablet
Reported
2017-07-07 12:48:46 PDT
As per
https://developer.apple.com/library/content/technotes/tn2277/_index.html#//apple_ref/doc/uid/DTS40010841-CH1-SUBSECTION2
, listening sockets should be closed when process is suspended. Otherwise, there is a risk for spinning in physicalsocketserver: select will return with a listening socket that should be read but accept will fail as there is nothing to read.
Attachments
Patch
(13.04 KB, patch)
2017-07-07 13:16 PDT
,
youenn fablet
no flags
Details
Formatted Diff
Diff
Patch
(13.07 KB, patch)
2017-07-07 14:04 PDT
,
youenn fablet
no flags
Details
Formatted Diff
Diff
Patch
(12.54 KB, patch)
2017-07-07 16:45 PDT
,
youenn fablet
no flags
Details
Formatted Diff
Diff
Patch
(11.95 KB, patch)
2017-07-07 17:17 PDT
,
youenn fablet
no flags
Details
Formatted Diff
Diff
Patch
(16.47 KB, patch)
2017-07-08 10:25 PDT
,
youenn fablet
no flags
Details
Formatted Diff
Diff
Fixing release logging
(16.53 KB, patch)
2017-07-08 17:55 PDT
,
youenn fablet
no flags
Details
Formatted Diff
Diff
Patch
(14.56 KB, patch)
2017-07-10 15:11 PDT
,
youenn fablet
no flags
Details
Formatted Diff
Diff
Show Obsolete
(6)
View All
Add attachment
proposed patch, testcase, etc.
youenn fablet
Comment 1
2017-07-07 12:50:41 PDT
Closing listening TCP sockets might be an issue in the case where we do WebRTC: - no a/v capture - Using server TCP sockets for the communication In that case, the connection will be closed and the web page will probably need to redo a negotiation and ICE gathering to continue exchanging data
youenn fablet
Comment 2
2017-07-07 12:54:15 PDT
rdar://problem/33139844
youenn fablet
Comment 3
2017-07-07 13:16:54 PDT
Created
attachment 314868
[details]
Patch
Chris Dumez
Comment 4
2017-07-07 13:31:53 PDT
Does not build?
youenn fablet
Comment 5
2017-07-07 14:04:52 PDT
Created
attachment 314876
[details]
Patch
Chris Dumez
Comment 6
2017-07-07 14:55:12 PDT
Comment on
attachment 314876
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=314876&action=review
> Source/WebKit2/ChangeLog:13 > + Tested through manual testing by going to a website doing WebRTC, homing out so that the network process is suspended and reopening Safari.
Indentation problem.
> Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h:67 > + bool needToCleanupForSuspension() const
Instead of having a separate method, can we just have cleanupForSuspension() call the completion handler right away if there is nothing to clean. I think it would simplify the code.
> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:645 > + RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::prepareToSuspend() Sending ProcessReadyToSuspend IPC message", this);
You need to update the method name in there.
> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:646 > + parentProcessConnection()->send(Messages::NetworkProcessProxy::ProcessReadyToSuspend(), 0);
We should ASSERT(!m_webProcessConnectionsToClean); in this method.
> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:653 > + if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes)
Not sure we need this check. Setting member to 0 does not hurt, right?
> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:661 > + if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes)
Not sure we need this check.
> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:662 > + m_webProcessConnectionsToClean++;
++m_webProcessConnectionsToClean;
> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:668 > + if (!--m_webProcessConnectionsToClean)
We should ASSERT(m_webProcessConnectionsToClean) before decrementing.
> Source/WebKit2/NetworkProcess/NetworkProcess.h:244 > + uint64_t m_webProcessConnectionsToClean { 0 };
how about just unsigned? Why 64 bit?
> Source/WebKit2/NetworkProcess/webrtc/NetworkRTCProvider.cpp:237 > + completionHandler();
Can we do this at the end of the function instead? This seems safer.
> Source/WebKit2/NetworkProcess/webrtc/NetworkRTCProvider.cpp:239 > + if (!m_connection)
This should not be an early return if you move the completionHandler call below.
youenn fablet
Comment 7
2017-07-07 15:37:33 PDT
Comment on
attachment 314876
[details]
Patch Thanks for the review. View in context:
https://bugs.webkit.org/attachment.cgi?id=314876&action=review
>> Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h:67 >> + bool needToCleanupForSuspension() const > > Instead of having a separate method, can we just have cleanupForSuspension() call the completion handler right away if there is nothing to clean. I think it would simplify the code.
In most cases, no cleanup will be done. If we do not do this, we will increment/decrement counters, call functions, create callbacks for nothing. Given the small added complexity, I slightly prefer the current approach. If we need to add more regular clean-up in the future, we can easily change that.
>> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:645 >> + RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::prepareToSuspend() Sending ProcessReadyToSuspend IPC message", this); > > You need to update the method name in there.
ok
>> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:646 >> + parentProcessConnection()->send(Messages::NetworkProcessProxy::ProcessReadyToSuspend(), 0); > > We should ASSERT(!m_webProcessConnectionsToClean); in this method.
ok
>> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:653 >> + if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) > > Not sure we need this check. Setting member to 0 does not hurt, right?
The issue is if processWillSuspendImminently is called while we still have some connections to clean. Then we will set m_webProcessConnectionsToClean to zero and it will get decremented later on.
>> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:661 >> + if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) > > Not sure we need this check.
We could get rid of it if we are sure that prepareToSuspend() is always called before processWillSuspendImminently(). I am not sure this is guaranteed.
>> Source/WebKit2/NetworkProcess/NetworkProcess.h:244 >> + uint64_t m_webProcessConnectionsToClean { 0 }; > > how about just unsigned? Why 64 bit?
yes, makes sense.
>> Source/WebKit2/NetworkProcess/webrtc/NetworkRTCProvider.cpp:237 >> + completionHandler(); > > Can we do this at the end of the function instead? This seems safer.
We can do both ways. It is ok to be suspended as soon as sockets are closed, which is ensured at this point. Doing IPC to notify the web process is optional.
Chris Dumez
Comment 8
2017-07-07 15:42:23 PDT
Comment on
attachment 314876
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=314876&action=review
>>> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:653 >>> + if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) >> >> Not sure we need this check. Setting member to 0 does not hurt, right? > > The issue is if processWillSuspendImminently is called while we still have some connections to clean. > Then we will set m_webProcessConnectionsToClean to zero and it will get decremented later on.
Hmm, I could see this happen indeed. Good point.
Chris Dumez
Comment 9
2017-07-07 15:49:53 PDT
Comment on
attachment 314876
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=314876&action=review
>>>> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:653 >>>> + if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) >>> >>> Not sure we need this check. Setting member to 0 does not hurt, right? >> >> The issue is if processWillSuspendImminently is called while we still have some connections to clean. >> Then we will set m_webProcessConnectionsToClean to zero and it will get decremented later on. > > Hmm, I could see this happen indeed. Good point.
We could also use something like: class DelayedReadyToSuspendScope : public RefCounted< DelayedReadyToSuspendScope > { DelayedReadyToSuspendScope(networkProcess, shouldAcknowledgeWhenReadyToSuspend); ~DelayedReadyToSuspendScope() { if (m_shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) m_networkProcess->notifyProcessReadyToSuspend() } private: m_shouldAcknowledgeWhenReadyToSuspend; m_networkProcess; } Then you capture a RefPtr<> to this in each lambda.
Chris Dumez
Comment 10
2017-07-07 15:58:12 PDT
Comment on
attachment 314876
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=314876&action=review
>>>>> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:653 >>>>> + if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) >>>> >>>> Not sure we need this check. Setting member to 0 does not hurt, right? >>> >>> The issue is if processWillSuspendImminently is called while we still have some connections to clean. >>> Then we will set m_webProcessConnectionsToClean to zero and it will get decremented later on. >> >> Hmm, I could see this happen indeed. Good point. > > We could also use something like: > > class DelayedReadyToSuspendScope : public RefCounted< DelayedReadyToSuspendScope > { > DelayedReadyToSuspendScope(networkProcess, shouldAcknowledgeWhenReadyToSuspend); > > ~DelayedReadyToSuspendScope() > { > if (m_shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) > m_networkProcess->notifyProcessReadyToSuspend() > } > > private: > m_shouldAcknowledgeWhenReadyToSuspend; > m_networkProcess; > } > > Then you capture a RefPtr<> to this in each lambda.
We don't even need the shouldAcknowledgeWhenReadyToSuspend. This can be dealt with upon initial construction: RefPtr<DelayedReadyToSuspendScope> scope; if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) scope = adoptRef(DelayedReadyToSuspendScope(*this)); Then capture scope in the lambdas.
youenn fablet
Comment 11
2017-07-07 16:13:50 PDT
> We don't even need the shouldAcknowledgeWhenReadyToSuspend. This can be > dealt with upon initial construction: > RefPtr<DelayedReadyToSuspendScope> scope; > if (shouldAcknowledgeWhenReadyToSuspend == > ShouldAcknowledgeWhenReadyToSuspend::Yes) > scope = adoptRef(DelayedReadyToSuspendScope(*this)); > > Then capture scope in the lambdas.
Yep, sounds much better.
youenn fablet
Comment 12
2017-07-07 16:45:25 PDT
Created
attachment 314898
[details]
Patch
Build Bot
Comment 13
2017-07-07 16:48:04 PDT
Attachment 314898
[details]
did not pass style-queue: ERROR: Source/WebKit2/NetworkProcess/NetworkProcess.cpp:651: Should be indented on a separate line, with the colon or comma first on that line. [whitespace/indent] [4] Total errors found: 1 in 9 files If any of these errors are false positives, please file a bug against check-webkit-style.
Chris Dumez
Comment 14
2017-07-07 16:53:57 PDT
Comment on
attachment 314898
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=314898&action=review
> Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h:67 > + bool needToCleanupForSuspension() const
I still don't like that we have this function. The complexity should be inside cleanupForSuspension(), not at the call site. Also, the API is risky since it will crash if you call cleanupForSuspension() without checking needToCleanupForSuspension() first. I still think the m_rtcProvider check should be inside cleanupForSuspension().
Chris Dumez
Comment 15
2017-07-07 16:57:16 PDT
Comment on
attachment 314898
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=314898&action=review
> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:643 > +void NetworkProcess::notifyProcessReadyToSuspend()
Not sure we need a function for this. We could just move those 2 lines in the DelayedReadyToSuspendScope destructor.
> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:661 > + RefPtr<DelayedReadyToSuspendScope> delayedReadyToSuspend = (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) ? adoptRef(new DelayedReadyToSuspendScope(*this)) : nullptr;
No need for the parentheses.
youenn fablet
Comment 16
2017-07-07 17:17:59 PDT
Created
attachment 314902
[details]
Patch
Build Bot
Comment 17
2017-07-07 17:19:28 PDT
Attachment 314902
[details]
did not pass style-queue: ERROR: Source/WebKit2/NetworkProcess/NetworkProcess.cpp:651: Should be indented on a separate line, with the colon or comma first on that line. [whitespace/indent] [4] Total errors found: 1 in 9 files If any of these errors are false positives, please file a bug against check-webkit-style.
youenn fablet
Comment 18
2017-07-07 17:20:21 PDT
(In reply to youenn fablet from
comment #16
)
> Created
attachment 314902
[details]
> Patch
Removed two-step cleanup util. Will retest it on iOS over the weekend.
youenn fablet
Comment 19
2017-07-08 10:25:41 PDT
Created
attachment 314921
[details]
Patch
Build Bot
Comment 20
2017-07-08 10:58:33 PDT
Attachment 314921
[details]
did not pass style-queue: ERROR: Source/WebKit2/NetworkProcess/webrtc/NetworkRTCProvider.cpp:225: Should be indented on a separate line, with the colon or comma first on that line. [whitespace/indent] [4] ERROR: Source/WebKit2/NetworkProcess/NetworkProcess.cpp:645: Should be indented on a separate line, with the colon or comma first on that line. [whitespace/indent] [4] Total errors found: 2 in 9 files If any of these errors are false positives, please file a bug against check-webkit-style.
youenn fablet
Comment 21
2017-07-08 17:55:08 PDT
Created
attachment 314932
[details]
Fixing release logging
Build Bot
Comment 22
2017-07-08 17:57:26 PDT
Attachment 314932
[details]
did not pass style-queue: ERROR: Source/WebKit2/NetworkProcess/webrtc/NetworkRTCProvider.cpp:225: Should be indented on a separate line, with the colon or comma first on that line. [whitespace/indent] [4] ERROR: Source/WebKit2/NetworkProcess/NetworkProcess.cpp:645: Should be indented on a separate line, with the colon or comma first on that line. [whitespace/indent] [4] Total errors found: 2 in 9 files If any of these errors are false positives, please file a bug against check-webkit-style.
Chris Dumez
Comment 23
2017-07-09 09:39:27 PDT
Promises in C++ code now? :( I have not looked in detail yet but the previous iteration seemed much simpler.
Chris Dumez
Comment 24
2017-07-09 10:11:41 PDT
Comment on
attachment 314932
[details]
Fixing release logging View in context:
https://bugs.webkit.org/attachment.cgi?id=314932&action=review
> Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp:192 > +std::optional<SuspensionResult> NetworkConnectionToWebProcess::cleanupForSuspension()
I would much prefer passing a lambda rather than returning an optional promise.
> Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp:198 > + return std::nullopt;
This could call the lambda right away, as I suggested previously.
> Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h:54 > +class SuspensionResult {
I don't think this added complexity is necessary. My previous review comments were about simplify the code.
> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:643 > +class TaskCounter : public RefCounted<TaskCounter> {
This looks extremely similar to WTF's RefCounter now.
youenn fablet
Comment 25
2017-07-09 21:03:39 PDT
Main change here is making sure no new TCP listening socket is created when we start closing them. That should give us full protection against occasional spins. Ideally we would close the listening sockets when resuming the process. That way we would not close the sockets in case of cancelled suspension. But the select/accept issue does not allow us that at the moment.
> > Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp:192 > > +std::optional<SuspensionResult> NetworkConnectionToWebProcess::cleanupForSuspension() > > I would much prefer passing a lambda rather than returning an optional > promise.
I like the way NetworkProcess::actualPrepareToSuspend is written. That makes NetworkProcess code clearer to me. I also like the fact of returning something instead of passing a parameter that we should make sure to call in every case. If this is a blocker, I am fine going with more lambdas.
> > Source/WebKit2/NetworkProcess/NetworkProcess.cpp:643 > > +class TaskCounter : public RefCounted<TaskCounter> { > > This looks extremely similar to WTF's RefCounter now.
Using RefCounter seems fine to me.
Chris Dumez
Comment 26
2017-07-10 08:38:24 PDT
I think lambdas are much simpler here. I do not see the point of introducing a new concept for this tiny piece of code.
youenn fablet
Comment 27
2017-07-10 15:11:28 PDT
Created
attachment 315034
[details]
Patch
youenn fablet
Comment 28
2017-07-10 15:11:52 PDT
(In reply to youenn fablet from
comment #27
)
> Created
attachment 315034
[details]
> Patch
Here is the version with lambdas
Build Bot
Comment 29
2017-07-10 16:06:39 PDT
Attachment 315034
[details]
did not pass style-queue: ERROR: Source/WebKit2/NetworkProcess/NetworkProcess.cpp:646: Should be indented on a separate line, with the colon or comma first on that line. [whitespace/indent] [4] Total errors found: 1 in 9 files If any of these errors are false positives, please file a bug against check-webkit-style.
Chris Dumez
Comment 30
2017-07-10 16:46:00 PDT
Comment on
attachment 315034
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=315034&action=review
Looks good otherwise.
> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:643 > +// FIXME: We can remove this one by adapting RefCounter.
I think we should do this. Why introduce a new class if there is a direct replacement? As far as I can tell, this is a trivial change, no? If so, why add a FIXME comment instead of doing it right?
youenn fablet
Comment 31
2017-07-10 17:41:10 PDT
(In reply to Chris Dumez from
comment #30
)
> Comment on
attachment 315034
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=315034&action=review
> > Looks good otherwise. > > > Source/WebKit2/NetworkProcess/NetworkProcess.cpp:643 > > +// FIXME: We can remove this one by adapting RefCounter. > > I think we should do this. Why introduce a new class if there is a direct > replacement? As far as I can tell, this is a trivial change, no? If so, why > add a FIXME comment instead of doing it right?
We need the counter value of RefCounter to trigger the IPC call when it is decremented to zero. This counter value is not passed to the lambda right now by RefCounter.
Chris Dumez
Comment 32
2017-07-10 18:18:53 PDT
Comment on
attachment 315034
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=315034&action=review
>>> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:643 >>> +// FIXME: We can remove this one by adapting RefCounter. >> >> I think we should do this. Why introduce a new class if there is a direct replacement? As far as I can tell, this is a trivial change, no? If so, why add a FIXME comment instead of doing it right? > > We need the counter value of RefCounter to trigger the IPC call when it is decremented to zero. > This counter value is not passed to the lambda right now by RefCounter.
You can get the counter value via RefCounter::value().
youenn fablet
Comment 33
2017-07-10 20:46:52 PDT
The lambda has no reference to the counter at the moment. I'll look at this refactoring when I will have some more time in a few weeks. I don't think this should block landing this patch.
Chris Dumez
Comment 34
2017-07-10 23:27:58 PDT
Comment on
attachment 315034
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=315034&action=review
>>>> Source/WebKit2/NetworkProcess/NetworkProcess.cpp:643 >>>> +// FIXME: We can remove this one by adapting RefCounter. >>> >>> I think we should do this. Why introduce a new class if there is a direct replacement? As far as I can tell, this is a trivial change, no? If so, why add a FIXME comment instead of doing it right? >> >> We need the counter value of RefCounter to trigger the IPC call when it is decremented to zero. >> This counter value is not passed to the lambda right now by RefCounter. > > You can get the counter value via RefCounter::value().
For the record, I preferred the previous version that had the IPC in its destructor. There is no point in making this generic and it is unlikely to be reused considering it is in a cpp file. I preferred the previous iteration because it resulted in simpler code below.
WebKit Commit Bot
Comment 35
2017-07-11 07:53:22 PDT
Comment on
attachment 315034
[details]
Patch Clearing flags on attachment: 315034 Committed
r219328
: <
http://trac.webkit.org/changeset/219328
>
WebKit Commit Bot
Comment 36
2017-07-11 07:53:24 PDT
All reviewed patches have been landed. Closing bug.
youenn fablet
Comment 37
2017-07-11 09:16:55 PDT
Thanks for the review.
> For the record, I preferred the previous version that had the IPC in its > destructor. There is no point in making this generic and it is unlikely to > be reused considering it is in a cpp file. > I preferred the previous iteration because it resulted in simpler code below.
This allowed removing the friend class TaskCounter declaration in WebPageProxy header. TaskCounter is probably not a very good name, improving it might be good for readability. As of reusability, let's decide what we want when looking at merging it with RefCounter.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug