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

Side by Side Diff: third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp

Issue 2638413004: Don't run removeFinishedSourceNodes with the context lock. (Closed)
Patch Set: Add removeFinishedSourceNodesOnMainThread Created 3 years, 11 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010, Google Inc. All rights reserved. 2 * Copyright (C) 2010, Google 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 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 void BaseAudioContext::notifyStateChange() { 626 void BaseAudioContext::notifyStateChange() {
627 dispatchEvent(Event::create(EventTypeNames::statechange)); 627 dispatchEvent(Event::create(EventTypeNames::statechange));
628 } 628 }
629 629
630 void BaseAudioContext::notifySourceNodeFinishedProcessing( 630 void BaseAudioContext::notifySourceNodeFinishedProcessing(
631 AudioHandler* handler) { 631 AudioHandler* handler) {
632 DCHECK(isAudioThread()); 632 DCHECK(isAudioThread());
633 m_finishedSourceHandlers.push_back(handler); 633 m_finishedSourceHandlers.push_back(handler);
634 } 634 }
635 635
636 void BaseAudioContext::removeFinishedSourceNodes() { 636 void BaseAudioContext::removeFinishedSourceNodes(bool needsRemoval) {
637 DCHECK(isAudioThread());
638
639 if (needsRemoval) {
640 Platform::current()->mainThread()->getWebTaskRunner()->postTask(
641 BLINK_FROM_HERE,
642 crossThreadBind(
643 &BaseAudioContext::removeFinishedSourceNodesOnMainThread,
644 wrapCrossThreadPersistent(this)));
645 }
646 }
647
648 void BaseAudioContext::removeFinishedSourceNodesOnMainThread() {
637 DCHECK(isMainThread()); 649 DCHECK(isMainThread());
638 AutoLocker locker(this); 650 AutoLocker locker(this);
639 // Quadratic worst case, but sizes of both vectors are considered 651 // Quadratic worst case, but sizes of both vectors are considered
640 // manageable, especially |m_finishedSourceNodes| is likely to be short. 652 // manageable, especially |m_finishedSourceNodes| is likely to be short.
641 for (AudioNode* node : m_finishedSourceNodes) { 653 for (AudioNode* node : m_finishedSourceNodes) {
642 size_t i = m_activeSourceNodes.find(node); 654 size_t i = m_activeSourceNodes.find(node);
643 if (i != kNotFound) 655 if (i != kNotFound)
644 m_activeSourceNodes.remove(i); 656 m_activeSourceNodes.remove(i);
645 } 657 }
646 m_finishedSourceNodes.clear(); 658 m_finishedSourceNodes.clear();
647 } 659 }
648 660
649 void BaseAudioContext::releaseFinishedSourceNodes() { 661 bool BaseAudioContext::releaseFinishedSourceNodes() {
650 ASSERT(isGraphOwner()); 662 ASSERT(isGraphOwner());
651 DCHECK(isAudioThread()); 663 DCHECK(isAudioThread());
652 bool didRemove = false; 664 bool didRemove = false;
653 for (AudioHandler* handler : m_finishedSourceHandlers) { 665 for (AudioHandler* handler : m_finishedSourceHandlers) {
654 for (AudioNode* node : m_activeSourceNodes) { 666 for (AudioNode* node : m_activeSourceNodes) {
655 if (m_finishedSourceNodes.contains(node)) 667 if (m_finishedSourceNodes.contains(node))
656 continue; 668 continue;
657 if (handler == &node->handler()) { 669 if (handler == &node->handler()) {
658 handler->breakConnection(); 670 handler->breakConnection();
659 m_finishedSourceNodes.add(node); 671 m_finishedSourceNodes.add(node);
660 didRemove = true; 672 didRemove = true;
661 break; 673 break;
662 } 674 }
663 } 675 }
664 } 676 }
665 if (didRemove)
666 Platform::current()->mainThread()->getWebTaskRunner()->postTask(
667 BLINK_FROM_HERE,
668 crossThreadBind(&BaseAudioContext::removeFinishedSourceNodes,
669 wrapCrossThreadPersistent(this)));
670
671 m_finishedSourceHandlers.clear(); 677 m_finishedSourceHandlers.clear();
678 return didRemove;
672 } 679 }
673 680
674 void BaseAudioContext::notifySourceNodeStartedProcessing(AudioNode* node) { 681 void BaseAudioContext::notifySourceNodeStartedProcessing(AudioNode* node) {
675 DCHECK(isMainThread()); 682 DCHECK(isMainThread());
676 AutoLocker locker(this); 683 AutoLocker locker(this);
677 684
678 m_activeSourceNodes.push_back(node); 685 m_activeSourceNodes.push_back(node);
679 node->handler().makeConnection(); 686 node->handler().makeConnection();
680 } 687 }
681 688
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 } 741 }
735 742
736 void BaseAudioContext::handlePostRenderTasks() { 743 void BaseAudioContext::handlePostRenderTasks() {
737 DCHECK(isAudioThread()); 744 DCHECK(isAudioThread());
738 745
739 // Must use a tryLock() here too. Don't worry, the lock will very rarely be 746 // Must use a tryLock() here too. Don't worry, the lock will very rarely be
740 // contended and this method is called frequently. The worst that can happen 747 // contended and this method is called frequently. The worst that can happen
741 // is that there will be some nodes which will take slightly longer than usual 748 // is that there will be some nodes which will take slightly longer than usual
742 // to be deleted or removed from the render graph (in which case they'll 749 // to be deleted or removed from the render graph (in which case they'll
743 // render silence). 750 // render silence).
751 bool didRemove = false;
744 if (tryLock()) { 752 if (tryLock()) {
745 // Take care of AudioNode tasks where the tryLock() failed previously. 753 // Take care of AudioNode tasks where the tryLock() failed previously.
746 deferredTaskHandler().breakConnections(); 754 deferredTaskHandler().breakConnections();
747 755
748 // Dynamically clean up nodes which are no longer needed. 756 // Dynamically clean up nodes which are no longer needed.
749 releaseFinishedSourceNodes(); 757 didRemove = releaseFinishedSourceNodes();
750 758
751 deferredTaskHandler().handleDeferredTasks(); 759 deferredTaskHandler().handleDeferredTasks();
752 deferredTaskHandler().requestToDeleteHandlersOnMainThread(); 760 deferredTaskHandler().requestToDeleteHandlersOnMainThread();
753 761
754 unlock(); 762 unlock();
755 } 763 }
764
765 removeFinishedSourceNodes(didRemove);
hongchan 2017/01/20 23:27:05 What's the difference between doing the above and
Raymond Toy 2017/01/21 00:12:15 Mostly less duplication in the two places that cal
hongchan 2017/01/23 17:38:41 What I meant by the comment above is: why do we ha
Raymond Toy 2017/01/23 17:45:01 Just to make the logic of what to do with didRemov
hongchan 2017/01/23 18:08:06 Okay, probably this will be the last question; can
Raymond Toy 2017/01/23 18:11:20 Let me try. You mean DeferredTaskHandler? (Not su
756 } 766 }
757 767
758 void BaseAudioContext::resolvePromisesForResumeOnMainThread() { 768 void BaseAudioContext::resolvePromisesForResumeOnMainThread() {
759 DCHECK(isMainThread()); 769 DCHECK(isMainThread());
760 AutoLocker locker(this); 770 AutoLocker locker(this);
761 771
762 for (auto& resolver : m_resumeResolvers) { 772 for (auto& resolver : m_resumeResolvers) {
763 if (m_contextState == Closed) { 773 if (m_contextState == Closed) {
764 resolver->reject(DOMException::create( 774 resolver->reject(DOMException::create(
765 InvalidStateError, "Cannot resume a context that has been closed")); 775 InvalidStateError, "Cannot resume a context that has been closed"));
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 } 902 }
893 903
894 SecurityOrigin* BaseAudioContext::getSecurityOrigin() const { 904 SecurityOrigin* BaseAudioContext::getSecurityOrigin() const {
895 if (getExecutionContext()) 905 if (getExecutionContext())
896 return getExecutionContext()->getSecurityOrigin(); 906 return getExecutionContext()->getSecurityOrigin();
897 907
898 return nullptr; 908 return nullptr;
899 } 909 }
900 910
901 } // namespace blink 911 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698