Bug 217442 - Constructing a AudioWorkletNode should construct an AudioWorkletProcessor on the Worklet thread
Summary: Constructing a AudioWorkletNode should construct an AudioWorkletProcessor on ...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit2 (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Chris Dumez
URL:
Keywords: InRadar
Depends on:
Blocks: 217058
  Show dependency treegraph
 
Reported: 2020-10-07 13:17 PDT by Chris Dumez
Modified: 2020-10-07 17:28 PDT (History)
17 users (show)

See Also:


Attachments
Patch (62.04 KB, patch)
2020-10-07 13:41 PDT, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (61.95 KB, patch)
2020-10-07 13:44 PDT, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (65.55 KB, patch)
2020-10-07 15:06 PDT, Chris Dumez
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Dumez 2020-10-07 13:17:17 PDT
Constructing a AudioWorkletNode should construct an AudioWorkletProcessor on the Worklet thread:
- https://www.w3.org/TR/webaudio/#AudioWorkletNode-constructors (Step 13)
Comment 1 Chris Dumez 2020-10-07 13:41:15 PDT
Created attachment 410773 [details]
Patch
Comment 2 Chris Dumez 2020-10-07 13:44:09 PDT
Created attachment 410774 [details]
Patch
Comment 3 Geoffrey Garen 2020-10-07 14:39:22 PDT
Comment on attachment 410774 [details]
Patch

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

> Source/WebCore/Modules/webaudio/AudioWorkletNode.cpp:144
>  AudioWorkletNode::~AudioWorkletNode()
>  {
> +    ASSERT(isMainThread());
> +    if (m_processor) {
> +        if (auto* workletProxy = context().audioWorklet().proxy())
> +            workletProxy->postTaskForModeToWorkletGlobalScope([m_processor = WTFMove(m_processor)](ScriptExecutionContext&) { }, WorkerRunLoop::defaultMode());
> +    }
>      uninitialize();
>  }
>  
> +void AudioWorkletNode::setProcessor(RefPtr<AudioWorkletProcessor>&& processor)
> +{
> +    ASSERT(!isMainThread());
> +    m_processor = WTFMove(processor);
> +}

This doesn't look right to me. m_processor is set on the worklet thread but checked on the main thread, which seems like a data race. Maybe it's not a real problem in practice because something guarantees synchronization before destruction. But I'd prefer not to have think that hard.

Can we have the worklet thread do the construction and then have the main thread do the assignment?
Comment 4 Chris Dumez 2020-10-07 14:42:22 PDT
(In reply to Geoffrey Garen from comment #3)
> Comment on attachment 410774 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=410774&action=review
> 
> > Source/WebCore/Modules/webaudio/AudioWorkletNode.cpp:144
> >  AudioWorkletNode::~AudioWorkletNode()
> >  {
> > +    ASSERT(isMainThread());
> > +    if (m_processor) {
> > +        if (auto* workletProxy = context().audioWorklet().proxy())
> > +            workletProxy->postTaskForModeToWorkletGlobalScope([m_processor = WTFMove(m_processor)](ScriptExecutionContext&) { }, WorkerRunLoop::defaultMode());
> > +    }
> >      uninitialize();
> >  }
> >  
> > +void AudioWorkletNode::setProcessor(RefPtr<AudioWorkletProcessor>&& processor)
> > +{
> > +    ASSERT(!isMainThread());
> > +    m_processor = WTFMove(processor);
> > +}
> 
> This doesn't look right to me. m_processor is set on the worklet thread but
> checked on the main thread, which seems like a data race. Maybe it's not a
> real problem in practice because something guarantees synchronization before
> destruction. But I'd prefer not to have think that hard.
> 
> Can we have the worklet thread do the construction and then have the main
> thread do the assignment?

I don't think your proposal is better for the long term since AudioWorkletNode::process() will use m_processor on the rendering thread to do audio processing.

How about I add a Lock to synchronize?
Comment 5 Chris Dumez 2020-10-07 15:06:01 PDT
Created attachment 410789 [details]
Patch
Comment 6 Geoffrey Garen 2020-10-07 15:56:51 PDT
Comment on attachment 410789 [details]
Patch

r=me
Comment 7 Geoffrey Garen 2020-10-07 16:00:40 PDT
> I don't think your proposal is better for the long term since
> AudioWorkletNode::process() will use m_processor on the rendering thread to
> do audio processing.
> 
> How about I add a Lock to synchronize?

I guess I don't have the full context, so I'll try to evaluate in future patches.

If AudioWorkletNode::process() might need m_processor right away, and can't wait for AudioWorklet::createProcessor() to call back to the main thread, it sounds like the right solution might be for AudioWorklet::createProcessor to wait synchronously on a semaphore until the processor has been created. Otherwise, a lock may have the same issues as a post-back to the main thread.
Comment 8 EWS 2020-10-07 16:31:30 PDT
Committed r268161: <https://trac.webkit.org/changeset/268161>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 410789 [details].
Comment 9 Radar WebKit Bug Importer 2020-10-07 16:32:20 PDT
<rdar://problem/70070509>
Comment 10 Fujii Hironori 2020-10-07 17:09:22 PDT
Comment on attachment 410789 [details]
Patch

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

> Source/WebCore/dom/ScriptExecutionContext.cpp:211
> +#if ENABLE(WEB_AUDIO)

AppleWin and WinCairo debug builder can't compile this. I'm suprised by using #if in ASSERT condition.

https://build.webkit.org/builders/Apple%20Win%2010%20Debug%20%28Build%29/builds/16462

> C:\cygwin\home\buildbot\worker\win10-debug\build\Source\WebCore\dom/ScriptExecutionContext.cpp(214,1): error C2121: '#': invalid character: possibly the result of a macro expansion (compiling source file C:\cygwin\home\buildbot\worker\win10-debug\build\WebKitBuild\Debug\DerivedSources\WebCore\unified-sources\UnifiedSource-be65d27a-16.cpp) [C:\cygwin\home\buildbot\worker\win10-debug\build\WebKitBuild\Debug\Source\WebCore\WebCore.vcxproj]
Comment 11 Chris Dumez 2020-10-07 17:17:05 PDT
(In reply to Fujii Hironori from comment #10)
> Comment on attachment 410789 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=410789&action=review
> 
> > Source/WebCore/dom/ScriptExecutionContext.cpp:211
> > +#if ENABLE(WEB_AUDIO)
> 
> AppleWin and WinCairo debug builder can't compile this. I'm suprised by
> using #if in ASSERT condition.
> 
> https://build.webkit.org/builders/Apple%20Win%2010%20Debug%20%28Build%29/
> builds/16462
> 
> > C:\cygwin\home\buildbot\worker\win10-debug\build\Source\WebCore\dom/ScriptExecutionContext.cpp(214,1): error C2121: '#': invalid character: possibly the result of a macro expansion (compiling source file C:\cygwin\home\buildbot\worker\win10-debug\build\WebKitBuild\Debug\DerivedSources\WebCore\unified-sources\UnifiedSource-be65d27a-16.cpp) [C:\cygwin\home\buildbot\worker\win10-debug\build\WebKitBuild\Debug\Source\WebCore\WebCore.vcxproj]

Ok. Looking into fixing it.
Comment 12 Chris Dumez 2020-10-07 17:28:06 PDT
(In reply to Chris Dumez from comment #11)
> (In reply to Fujii Hironori from comment #10)
> > Comment on attachment 410789 [details]
> > Patch
> > 
> > View in context:
> > https://bugs.webkit.org/attachment.cgi?id=410789&action=review
> > 
> > > Source/WebCore/dom/ScriptExecutionContext.cpp:211
> > > +#if ENABLE(WEB_AUDIO)
> > 
> > AppleWin and WinCairo debug builder can't compile this. I'm suprised by
> > using #if in ASSERT condition.
> > 
> > https://build.webkit.org/builders/Apple%20Win%2010%20Debug%20%28Build%29/
> > builds/16462
> > 
> > > C:\cygwin\home\buildbot\worker\win10-debug\build\Source\WebCore\dom/ScriptExecutionContext.cpp(214,1): error C2121: '#': invalid character: possibly the result of a macro expansion (compiling source file C:\cygwin\home\buildbot\worker\win10-debug\build\WebKitBuild\Debug\DerivedSources\WebCore\unified-sources\UnifiedSource-be65d27a-16.cpp) [C:\cygwin\home\buildbot\worker\win10-debug\build\WebKitBuild\Debug\Source\WebCore\WebCore.vcxproj]
> 
> Ok. Looking into fixing it.

Follow-up build fix in <https://trac.webkit.org/changeset/268164>.