Bug 224758

Summary: Fix races in LibWebRTCCodecs introduced in r276214
Product: WebKit Reporter: Chris Dumez <cdumez>
Component: WebKit2Assignee: Chris Dumez <cdumez>
Status: RESOLVED FIXED    
Severity: Normal CC: darin, kkinnunen, lingcherd_ho, webkit-bug-importer, youennf
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
Bug Depends on:    
Bug Blocks: 224704    
Attachments:
Description Flags
Patch
none
Patch
none
Patch none

Description Chris Dumez 2021-04-19 07:49:04 PDT
Fix races in LibWebRTCCodecs introduced in r276214.
Comment 1 Chris Dumez 2021-04-19 07:52:47 PDT
Created attachment 426418 [details]
Patch
Comment 2 youenn fablet 2021-04-19 08:42:16 PDT
Comment on attachment 426418 [details]
Patch

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

> Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp:262
> +    ensureGPUProcessConnectionAndDispatchToThread([this, decoderIdentifier = decoder.identifier] {

Maybe add a comment in ensureGPUProcessConnectionAndDispatchToThread that the m_connection lock needs to be kept for the dispatchToThread call in ensureGPUProcessConnectionAndDispatchToThread/ensureOnMainRunLoop.

Also, let's look at the following case:
- createEncoder goes to main thread as connection is null.
- initializeEncoder goes to main thread as connection is null.
- createEncoder callback is in main thread, creates the connection, goes to the codec queue.
- releaseEncoder goes to the codec queue as connection is no longer null.
- initializeEncoder callback is in the main thread and goes to the codec queue.

We probably can have initializeEncoder happening after releaseEncoder in the codec queue.

We could accept the raciness of initializeEncoder, and add a if(auto* encoder...) in its implementation.
We could also store a goThroughMainThread state in encoder/decoder structures, less subtle and probably stronger.
Comment 3 Chris Dumez 2021-04-19 08:53:33 PDT
(In reply to youenn fablet from comment #2)
> Comment on attachment 426418 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=426418&action=review
> 
> > Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp:262
> > +    ensureGPUProcessConnectionAndDispatchToThread([this, decoderIdentifier = decoder.identifier] {
> 
> Maybe add a comment in ensureGPUProcessConnectionAndDispatchToThread that
> the m_connection lock needs to be kept for the dispatchToThread call in
> ensureGPUProcessConnectionAndDispatchToThread/ensureOnMainRunLoop.
> 
> Also, let's look at the following case:
> - createEncoder goes to main thread as connection is null.
> - initializeEncoder goes to main thread as connection is null.
> - createEncoder callback is in main thread, creates the connection, goes to
> the codec queue.
> - releaseEncoder goes to the codec queue as connection is no longer null.
> - initializeEncoder callback is in the main thread and goes to the codec
> queue.
> 
> We probably can have initializeEncoder happening after releaseEncoder in the
> codec queue.
> 
> We could accept the raciness of initializeEncoder, and add a if(auto*
> encoder...) in its implementation.

Even that wouldn't be safe I think. You could imagine createDecoder getting called first, then createEncoder, then initializeEncoder in your scenario. initializeEncoder would get received before createEncoder which would be bad.

> We could also store a goThroughMainThread state in encoder/decoder
> structures, less subtle and probably stronger.
Comment 4 Chris Dumez 2021-04-19 09:18:53 PDT
(In reply to Chris Dumez from comment #3)
> (In reply to youenn fablet from comment #2)
> > Comment on attachment 426418 [details]
> > Patch
> > 
> > View in context:
> > https://bugs.webkit.org/attachment.cgi?id=426418&action=review
> > 
> > > Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp:262
> > > +    ensureGPUProcessConnectionAndDispatchToThread([this, decoderIdentifier = decoder.identifier] {
> > 
> > Maybe add a comment in ensureGPUProcessConnectionAndDispatchToThread that
> > the m_connection lock needs to be kept for the dispatchToThread call in
> > ensureGPUProcessConnectionAndDispatchToThread/ensureOnMainRunLoop.
> > 
> > Also, let's look at the following case:
> > - createEncoder goes to main thread as connection is null.
> > - initializeEncoder goes to main thread as connection is null.
> > - createEncoder callback is in main thread, creates the connection, goes to
> > the codec queue.
> > - releaseEncoder goes to the codec queue as connection is no longer null.
> > - initializeEncoder callback is in the main thread and goes to the codec
> > queue.
> > 
> > We probably can have initializeEncoder happening after releaseEncoder in the
> > codec queue.
> > 
> > We could accept the raciness of initializeEncoder, and add a if(auto*
> > encoder...) in its implementation.
> 
> Even that wouldn't be safe I think. You could imagine createDecoder getting
> called first, then createEncoder, then initializeEncoder in your scenario.
> initializeEncoder would get received before createEncoder which would be bad.

I have a proposal that would address that. I am polishing the patch and will upload shortly.
Comment 5 Chris Dumez 2021-04-19 09:24:42 PDT
Created attachment 426433 [details]
Patch
Comment 6 youenn fablet 2021-04-19 09:42:54 PDT
Comment on attachment 426433 [details]
Patch

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

> Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp:202
> +    if (m_connection) {

I would put that first since this is the fast path.

> Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp:213
> +            dispatchToThread(m_tasksToDispatchAfterEstablishingConnection.takeFirst());

Seems like we could use a Vector.
Comment 7 Chris Dumez 2021-04-19 09:53:36 PDT
Created attachment 426437 [details]
Patch
Comment 8 EWS 2021-04-19 10:53:11 PDT
Committed r276263 (236745@main): <https://commits.webkit.org/236745@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 426437 [details].
Comment 9 Ling Ho 2021-04-23 03:01:28 PDT
rdar://76852677