Changeset 275933 in webkit
- Timestamp:
- Apr 13, 2021, 11:12:15 PM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
-
ChangeLog (modified) (1 diff)
-
platform/graphics/avfoundation/AudioSourceProviderAVFObjC.h (modified) (1 diff)
-
platform/graphics/avfoundation/AudioSourceProviderAVFObjC.mm (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r275931 r275933 1 2021-04-13 Kimmo Kinnunen <kkinnunen@apple.com> 2 3 AudioSourceProviderAVFObjC should lock all multithreaded objects 4 https://bugs.webkit.org/show_bug.cgi?id=224230 5 6 Reviewed by Eric Carlson. 7 8 Lock following objects with TapStorage::lock: 9 AudioSourceProviderAVFObjC::m_tapStorage 10 AudioSourceProviderAVFObjC::m_avPlayerItem 11 12 Do not clear the tapStorage nor the _this pointer from 13 the audio thread. This is a race that cannot be overcome 14 since the main thread needs to access the m_tapStorage pointer to 15 lock the m_tapStorage pointer for modification. 16 17 Initialize m_tap in more robust way, in case initialization fails. 18 19 Do not leave stale m_tapStorage present when destroying the mixer. 20 21 * platform/graphics/avfoundation/AudioSourceProviderAVFObjC.h: 22 * platform/graphics/avfoundation/AudioSourceProviderAVFObjC.mm: 23 (WebCore::AudioSourceProviderAVFObjC::~AudioSourceProviderAVFObjC): 24 (WebCore::AudioSourceProviderAVFObjC::destroyMixIfNeeded): 25 (WebCore::AudioSourceProviderAVFObjC::createMixIfNeeded): 26 (WebCore::AudioSourceProviderAVFObjC::initCallback): 27 (WebCore::AudioSourceProviderAVFObjC::finalizeCallback): 28 1 29 2021-04-13 Fujii Hironori <Hironori.Fujii@sony.com> 2 30 -
trunk/Source/WebCore/platform/graphics/avfoundation/AudioSourceProviderAVFObjC.h
r275897 r275933 86 86 static void processCallback(MTAudioProcessingTapRef, CMItemCount, MTAudioProcessingTapFlags, AudioBufferList*, CMItemCount*, MTAudioProcessingTapFlags*); 87 87 88 void init(void* clientInfo, void** tapStorageOut);89 void finalize();90 88 void prepare(CMItemCount maxFrames, const AudioStreamBasicDescription *processingFormat); 91 89 void unprepare(); -
trunk/Source/WebCore/platform/graphics/avfoundation/AudioSourceProviderAVFObjC.mm
r275897 r275933 87 87 AudioSourceProviderAVFObjC::~AudioSourceProviderAVFObjC() 88 88 { 89 // FIXME: this is not correct, as this indicates that there might be simultaneous calls 90 // to the destructor and a member function. This undefined behavior will be addressed in the future 91 // commits. https://bugs.webkit.org/show_bug.cgi?id=224480 89 92 setClient(nullptr); 90 if (m_tapStorage) {91 auto locker = holdLock(m_tapStorage->lock);92 m_tapStorage->_this = nullptr;93 }94 95 m_tapStorage = nullptr;96 93 } 97 94 … … 186 183 if (!m_avAudioMix) 187 184 return; 188 185 ASSERT(m_tapStorage); 186 auto locker = holdLock(m_tapStorage->lock); 189 187 if (m_avPlayerItem) 190 188 [m_avPlayerItem setAudioMix:nil]; … … 192 190 m_avAudioMix.clear(); 193 191 m_tap.clear(); 192 m_tapStorage->_this = nullptr; 193 m_tapStorage = nullptr; 194 // Call unprepare, since Tap cannot call it after clear. 195 unprepare(); 194 196 m_weakFactory.revokeAll(); 195 197 } … … 201 203 202 204 ASSERT(!m_avAudioMix); 203 204 m_avAudioMix = adoptNS([PAL::allocAVMutableAudioMixInstance() init]); 205 ASSERT(!m_tapStorage); 206 ASSERT(!m_tap); 207 208 auto tapStorage = adoptRef(new TapStorage(this)); 209 auto locker = holdLock(tapStorage->lock); 205 210 206 211 MTAudioProcessingTapCallbacks callbacks = { 207 212 0, 208 t his,213 tapStorage.get(), 209 214 initCallback, 210 215 finalizeCallback, … … 216 221 MTAudioProcessingTapRef tap = nullptr; 217 222 OSStatus status = MTAudioProcessingTapCreate(kCFAllocatorDefault, &callbacks, 1, &tap); 218 ASSERT(tap);219 ASSERT(m_tap == tap);220 223 if (status != noErr) { 221 m_tap = nullptr; 222 return; 223 } 224 if (tap) 225 CFRelease(tap); 226 return; 227 } 228 m_tap = adoptCF(tap); 229 m_tapStorage = WTFMove(tapStorage); 230 m_avAudioMix = adoptNS([PAL::allocAVMutableAudioMixInstance() init]); 224 231 225 232 RetainPtr<AVMutableAudioMixInputParameters> parameters = adoptNS([PAL::allocAVMutableAudioMixInputParametersInstance() init]); … … 236 243 void AudioSourceProviderAVFObjC::initCallback(MTAudioProcessingTapRef tap, void* clientInfo, void** tapStorageOut) 237 244 { 238 ASSERT(tap); 239 AudioSourceProviderAVFObjC* _this = static_cast<AudioSourceProviderAVFObjC*>(clientInfo); 240 _this->m_tap = adoptCF(tap); 241 _this->m_tapStorage = adoptRef(new TapStorage(_this)); 242 _this->init(clientInfo, tapStorageOut); 243 *tapStorageOut = _this->m_tapStorage.get(); 244 245 ASSERT_UNUSED(tap, tap); 246 TapStorage* tapStorage = static_cast<TapStorage*>(clientInfo); 247 *tapStorageOut = tapStorage; 245 248 // ref balanced by deref in finalizeCallback: 246 _this->m_tapStorage->ref();249 tapStorage->ref(); 247 250 } 248 251 … … 251 254 ASSERT(tap); 252 255 TapStorage* tapStorage = static_cast<TapStorage*>(MTAudioProcessingTapGetStorage(tap)); 253 254 {255 auto locker = holdLock(tapStorage->lock);256 if (tapStorage->_this)257 tapStorage->_this->finalize();258 }259 256 tapStorage->deref(); 260 257 } … … 291 288 if (tapStorage->_this) 292 289 tapStorage->_this->process(tap, numberFrames, flags, bufferListInOut, numberFramesOut, flagsOut); 293 }294 295 void AudioSourceProviderAVFObjC::init(void* clientInfo, void** tapStorageOut)296 {297 ASSERT(clientInfo == this);298 UNUSED_PARAM(clientInfo);299 *tapStorageOut = this;300 }301 302 void AudioSourceProviderAVFObjC::finalize()303 {304 if (m_tapStorage) {305 m_tapStorage->_this = nullptr;306 m_tapStorage = nullptr;307 }308 290 } 309 291
Note:
See TracChangeset
for help on using the changeset viewer.