Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: Source/core/html/HTMLMediaElement.cpp

Issue 1193383002: Oilpan: have media element prefinalizer handle all finalization. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: move conditional closing of MediaSource to media elt prefinalizer Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/html/HTMLMediaElement.h ('k') | Source/modules/mediasource/MediaSource.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 , m_sentStalledEvent(false) 350 , m_sentStalledEvent(false)
351 , m_sentEndEvent(false) 351 , m_sentEndEvent(false)
352 , m_closedCaptionsVisible(false) 352 , m_closedCaptionsVisible(false)
353 , m_completelyLoaded(false) 353 , m_completelyLoaded(false)
354 , m_havePreparedToPlay(false) 354 , m_havePreparedToPlay(false)
355 , m_tracksAreReady(true) 355 , m_tracksAreReady(true)
356 , m_haveVisibleTextTrack(false) 356 , m_haveVisibleTextTrack(false)
357 , m_processingPreferenceChange(false) 357 , m_processingPreferenceChange(false)
358 , m_remoteRoutesAvailable(false) 358 , m_remoteRoutesAvailable(false)
359 , m_playingRemotely(false) 359 , m_playingRemotely(false)
360 #if ENABLE(OILPAN)
361 , m_isFinalizing(false) 360 , m_isFinalizing(false)
362 , m_closeMediaSourceWhenFinalizing(false)
363 #endif
364 , m_initialPlayWithoutUserGestures(false) 361 , m_initialPlayWithoutUserGestures(false)
365 , m_autoplayMediaCounted(false) 362 , m_autoplayMediaCounted(false)
366 , m_audioTracks(AudioTrackList::create(*this)) 363 , m_audioTracks(AudioTrackList::create(*this))
367 , m_videoTracks(VideoTrackList::create(*this)) 364 , m_videoTracks(VideoTrackList::create(*this))
368 , m_textTracks(nullptr) 365 , m_textTracks(nullptr)
369 #if ENABLE(WEB_AUDIO) 366 #if ENABLE(WEB_AUDIO)
370 , m_audioSourceNode(nullptr) 367 , m_audioSourceNode(nullptr)
371 #endif 368 #endif
372 { 369 {
373 #if ENABLE(OILPAN) 370 #if ENABLE(OILPAN)
374 ThreadState::current()->registerPreFinalizer(*this); 371 ThreadState::current()->registerPreFinalizer(*this);
375 #endif 372 #endif
376 ASSERT(RuntimeEnabledFeatures::mediaEnabled()); 373 ASSERT(RuntimeEnabledFeatures::mediaEnabled());
377 374
378 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); 375 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this);
379 376
380 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture()) 377 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture())
381 m_userGestureRequiredForPlay = true; 378 m_userGestureRequiredForPlay = true;
382 379
383 setHasCustomStyleCallbacks(); 380 setHasCustomStyleCallbacks();
384 addElementToDocumentMap(this, &document); 381 addElementToDocumentMap(this, &document);
385 } 382 }
386 383
387 HTMLMediaElement::~HTMLMediaElement() 384 HTMLMediaElement::~HTMLMediaElement()
388 { 385 {
389 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this); 386 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this);
390 387 #if !ENABLE(OILPAN)
391 #if ENABLE(OILPAN)
392 if (m_closeMediaSourceWhenFinalizing)
393 closeMediaSource();
394
395 // Oilpan: the player must be released, but the player object
396 // cannot safely access this player client any longer as parts of
397 // it may have been finalized already (like the media element's
398 // supplementable table.) Handled for now by entering an
399 // is-finalizing state, which is explicitly checked for if the
400 // player tries to access the media element during shutdown.
401 //
402 // FIXME: Oilpan: move the media player to the heap instead and
403 // avoid having to finalize it from here; this whole #if block
404 // could then be removed (along with the state bit it depends on.)
405 // crbug.com/378229
406 m_isFinalizing = true;
407 #else
408 // HTMLMediaElement and m_asyncEventQueue always become unreachable 388 // HTMLMediaElement and m_asyncEventQueue always become unreachable
409 // together. So HTMLMediaElement and m_asyncEventQueue are destructed in 389 // together. So HTMLMediaElement and m_asyncEventQueue are destructed in
410 // the same GC. We don't need to close it explicitly in Oilpan. 390 // the same GC. We don't need to close it explicitly in Oilpan.
411 m_asyncEventQueue->close(); 391 m_asyncEventQueue->close();
412 392
413 setShouldDelayLoadEvent(false); 393 setShouldDelayLoadEvent(false);
414 394
415 if (m_textTracks) 395 if (m_textTracks)
416 m_textTracks->clearOwner(); 396 m_textTracks->clearOwner();
417 m_audioTracks->shutdown(); 397 m_audioTracks->shutdown();
418 m_videoTracks->shutdown(); 398 m_videoTracks->shutdown();
419 399
420 if (m_mediaController) { 400 if (m_mediaController) {
421 m_mediaController->removeMediaElement(this); 401 m_mediaController->removeMediaElement(this);
422 m_mediaController = nullptr; 402 m_mediaController = nullptr;
423 } 403 }
424 closeMediaSource(); 404 closeMediaSource();
425 405
426 removeElementFromDocumentMap(this, &document()); 406 removeElementFromDocumentMap(this, &document());
427 #endif
428 407
429 // Destroying the player may cause a resource load to be canceled, 408 // Destroying the player may cause a resource load to be canceled,
430 // which could result in userCancelledLoad() being called back. 409 // which could result in userCancelledLoad() being called back.
431 // Setting m_completelyLoaded ensures that such a call will not cause 410 // Setting m_isFinalizing ensures that such a call will not cause
432 // us to dispatch an abort event, which would result in a crash. 411 // us to dispatch an abort event, which would result in a crash.
433 // See http://crbug.com/233654 for more details. 412 // See http://crbug.com/233654 for more details.
434 m_completelyLoaded = true; 413 m_isFinalizing = true;
435 414
436 // With Oilpan load events on the Document are always delayed during
437 // sweeping so we don't need to explicitly increment and decrement
438 // load event delay counts.
439 #if !ENABLE(OILPAN)
440 // Destroying the player may cause a resource load to be canceled, 415 // Destroying the player may cause a resource load to be canceled,
441 // which could result in Document::dispatchWindowLoadEvent() being 416 // which could result in Document::dispatchWindowLoadEvent() being
442 // called via ResourceFetch::didLoadResource() then 417 // called via ResourceFetch::didLoadResource() then
443 // FrameLoader::checkCompleted(). To prevent load event dispatching during 418 // FrameLoader::checkCompleted(). To prevent load event dispatching during
444 // object destruction, we use Document::incrementLoadEventDelayCount(). 419 // object destruction, we use Document::incrementLoadEventDelayCount().
445 // See http://crbug.com/275223 for more details. 420 // See http://crbug.com/275223 for more details.
446 document().incrementLoadEventDelayCount(); 421 document().incrementLoadEventDelayCount();
422
423 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
424
425 document().decrementLoadEventDelayCount();
447 #endif 426 #endif
448 427
428 #if ENABLE(WEB_AUDIO)
449 // m_audioSourceNode is explicitly cleared by AudioNode::dispose(). 429 // m_audioSourceNode is explicitly cleared by AudioNode::dispose().
450 // Since AudioNode::dispose() is guaranteed to be always called before 430 // Since AudioNode::dispose() is guaranteed to be always called before
451 // the AudioNode is destructed, m_audioSourceNode is explicitly cleared 431 // the AudioNode is destructed, m_audioSourceNode is explicitly cleared
452 // even if the AudioNode and the HTMLMediaElement die together. 432 // even if the AudioNode and the HTMLMediaElement die together.
453 #if ENABLE(WEB_AUDIO)
454 ASSERT(!m_audioSourceNode); 433 ASSERT(!m_audioSourceNode);
455 #endif 434 #endif
456 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
457
458 #if !ENABLE(OILPAN)
459 document().decrementLoadEventDelayCount();
460 #endif
461 } 435 }
462 436
463 #if ENABLE(OILPAN) 437 #if ENABLE(OILPAN)
464 void HTMLMediaElement::dispose() 438 void HTMLMediaElement::dispose()
465 { 439 {
466 // If the HTMLMediaElement dies with the Document we are not 440 // If the HTMLMediaElement dies with the Document we are not
467 // allowed to touch the Document to adjust delay load event counts 441 // allowed to touch the Document to adjust delay load event counts
468 // from the destructor, as the Document could have been already 442 // from the destructor, as the Document could have been already
469 // destructed. 443 // destructed.
470 // 444 //
471 // Work around that restriction by accessing the Document from 445 // Work around that restriction by accessing the Document from
472 // a prefinalizer action instead, updating its delayed load count. 446 // a prefinalizer action instead, updating its delayed load count.
473 // If needed - if the Document has been detached and informed its 447 // If needed - if the Document has been detached and informed its
474 // ContextLifecycleObservers (which HTMLMediaElement is) that 448 // ContextLifecycleObservers (which HTMLMediaElement is) that
475 // it is being destroyed, the connection to the Document will 449 // it is being destroyed, the connection to the Document will
476 // have been severed already, but in that case there is no need 450 // have been severed already, but in that case there is no need
477 // to update the delayed load count. But if the Document hasn't 451 // to update the delayed load count. But if the Document hasn't
478 // been detached cleanly from any frame or it isn't dying in the 452 // been detached cleanly from any frame or it isn't dying in the
479 // same GC, we do update the delayed load count from the prefinalizer. 453 // same GC, we do update the delayed load count from the prefinalizer.
480 if (ActiveDOMObject::executionContext()) 454 if (ActiveDOMObject::executionContext())
481 setShouldDelayLoadEvent(false); 455 setShouldDelayLoadEvent(false);
482 }
483 456
484 void HTMLMediaElement::setCloseMediaSourceWhenFinalizing() 457 // If the MediaSource object survived, notify that the media element
485 { 458 // didn't.
486 ASSERT(!m_closeMediaSourceWhenFinalizing); 459 if (Heap::isHeapObjectAlive(m_mediaSource))
487 m_closeMediaSourceWhenFinalizing = true; 460 closeMediaSource();
461
462 // Oilpan: the player must be released, but the player object
463 // cannot safely access this player client any longer as parts of
464 // it may have been finalized already (like the media element's
465 // supplementable table.) Handled for now by entering an
466 // is-finalizing state, which is explicitly checked for if the
467 // player tries to access the media element during shutdown.
468 //
469 // FIXME: Oilpan: move the media player to the heap instead and
470 // avoid having to finalize it from here; this whole #if block
471 // could then be removed (along with the state bit it depends on.)
472 // crbug.com/378229
473 m_isFinalizing = true;
474
475 clearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
488 } 476 }
489 #endif 477 #endif
490 478
491 void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument) 479 void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument)
492 { 480 {
493 WTF_LOG(Media, "HTMLMediaElement::didMoveToNewDocument(%p)", this); 481 WTF_LOG(Media, "HTMLMediaElement::didMoveToNewDocument(%p)", this);
494 482
495 if (m_shouldDelayLoadEvent) { 483 if (m_shouldDelayLoadEvent) {
496 document().incrementLoadEventDelayCount(); 484 document().incrementLoadEventDelayCount();
497 // Note: Keeping the load event delay count increment on oldDocument tha t was added 485 // Note: Keeping the load event delay count increment on oldDocument tha t was added
(...skipping 2491 matching lines...) Expand 10 before | Expand all | Expand 10 after
2989 2977
2990 void HTMLMediaElement::userCancelledLoad() 2978 void HTMLMediaElement::userCancelledLoad()
2991 { 2979 {
2992 WTF_LOG(Media, "HTMLMediaElement::userCancelledLoad(%p)", this); 2980 WTF_LOG(Media, "HTMLMediaElement::userCancelledLoad(%p)", this);
2993 2981
2994 // If the media data fetching process is aborted by the user: 2982 // If the media data fetching process is aborted by the user:
2995 2983
2996 // 1 - The user agent should cancel the fetching process. 2984 // 1 - The user agent should cancel the fetching process.
2997 clearMediaPlayer(-1); 2985 clearMediaPlayer(-1);
2998 2986
2999 if (m_networkState == NETWORK_EMPTY || m_completelyLoaded) 2987 if (m_networkState == NETWORK_EMPTY || m_completelyLoaded || m_isFinalizing)
3000 return; 2988 return;
3001 2989
3002 // 2 - Set the error attribute to a new MediaError object whose code attribu te is set to MEDIA_ERR_ABORTED. 2990 // 2 - Set the error attribute to a new MediaError object whose code attribu te is set to MEDIA_ERR_ABORTED.
3003 m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED); 2991 m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED);
3004 2992
3005 // 3 - Queue a task to fire a simple event named error at the media element. 2993 // 3 - Queue a task to fire a simple event named error at the media element.
3006 scheduleEvent(EventTypeNames::abort); 2994 scheduleEvent(EventTypeNames::abort);
3007 2995
3008 closeMediaSource(); 2996 closeMediaSource();
3009 2997
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after
3680 3668
3681 #if ENABLE(WEB_AUDIO) 3669 #if ENABLE(WEB_AUDIO)
3682 void HTMLMediaElement::clearWeakMembers(Visitor* visitor) 3670 void HTMLMediaElement::clearWeakMembers(Visitor* visitor)
3683 { 3671 {
3684 if (!Heap::isHeapObjectAlive(m_audioSourceNode) && audioSourceProvider()) 3672 if (!Heap::isHeapObjectAlive(m_audioSourceNode) && audioSourceProvider())
3685 audioSourceProvider()->setClient(nullptr); 3673 audioSourceProvider()->setClient(nullptr);
3686 } 3674 }
3687 #endif 3675 #endif
3688 3676
3689 } 3677 }
OLDNEW
« no previous file with comments | « Source/core/html/HTMLMediaElement.h ('k') | Source/modules/mediasource/MediaSource.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698