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

Side by Side Diff: Source/modules/webaudio/AudioNode.cpp

Issue 386403002: WebAudio: Split AudioNode::finishDeref into two parts. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: apply review comments Created 6 years, 5 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/modules/webaudio/AudioNode.h ('k') | no next file » | 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) 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 , m_nodeType(NodeTypeUnknown) 48 , m_nodeType(NodeTypeUnknown)
49 , m_context(context) 49 , m_context(context)
50 , m_sampleRate(sampleRate) 50 , m_sampleRate(sampleRate)
51 #if ENABLE(OILPAN) 51 #if ENABLE(OILPAN)
52 , m_keepAlive(adoptPtr(new Persistent<AudioNode>(this))) 52 , m_keepAlive(adoptPtr(new Persistent<AudioNode>(this)))
53 #endif 53 #endif
54 , m_lastProcessingTime(-1) 54 , m_lastProcessingTime(-1)
55 , m_lastNonSilentTime(-1) 55 , m_lastNonSilentTime(-1)
56 , m_normalRefCount(1) // start out with normal refCount == 1 (like WTF::RefC ounted class) 56 , m_normalRefCount(1) // start out with normal refCount == 1 (like WTF::RefC ounted class)
57 , m_connectionRefCount(0) 57 , m_connectionRefCount(0)
58 , m_wasDisconnected(false)
59 , m_isMarkedForDeletion(false) 58 , m_isMarkedForDeletion(false)
60 , m_isDisabled(false) 59 , m_isDisabled(false)
61 , m_channelCount(2) 60 , m_channelCount(2)
62 , m_channelCountMode(Max) 61 , m_channelCountMode(Max)
63 , m_channelInterpretation(AudioBus::Speakers) 62 , m_channelInterpretation(AudioBus::Speakers)
64 { 63 {
65 ScriptWrappable::init(this); 64 ScriptWrappable::init(this);
66 #if DEBUG_AUDIONODE_REFERENCES 65 #if DEBUG_AUDIONODE_REFERENCES
67 if (!s_isNodeCountInitialized) { 66 if (!s_isNodeCountInitialized) {
68 s_isNodeCountInitialized = true; 67 s_isNodeCountInitialized = true;
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 { 484 {
486 atomicIncrement(&m_connectionRefCount); 485 atomicIncrement(&m_connectionRefCount);
487 // See the disabling code in finishDeref() below. This handles the case 486 // See the disabling code in finishDeref() below. This handles the case
488 // where a node is being re-connected after being used at least once and 487 // where a node is being re-connected after being used at least once and
489 // disconnected. In this case, we need to re-enable. 488 // disconnected. In this case, we need to re-enable.
490 enableOutputsIfNecessary(); 489 enableOutputsIfNecessary();
491 } 490 }
492 491
493 void AudioNode::deref() 492 void AudioNode::deref()
494 { 493 {
495 // The actually work for deref happens completely within the audio context's graph lock. 494 // The actual work for deref happens completely within the audio context's
496 // In the case of the audio thread, we must use a tryLock to avoid glitches. 495 // graph lock. In the case of the audio thread, we must use a tryLock to
496 // avoid glitches.
497 bool hasLock = false; 497 bool hasLock = false;
498 bool mustReleaseLock = false; 498 bool mustReleaseLock = false;
499 499
500 if (context()->isAudioThread()) { 500 if (context()->isAudioThread()) {
501 // Real-time audio thread must not contend lock (to avoid glitches). 501 // Real-time audio thread must not contend lock (to avoid glitches).
502 hasLock = context()->tryLock(mustReleaseLock); 502 hasLock = context()->tryLock(mustReleaseLock);
503 } else { 503 } else {
504 context()->lock(mustReleaseLock); 504 context()->lock(mustReleaseLock);
505 hasLock = true; 505 hasLock = true;
506 } 506 }
(...skipping 12 matching lines...) Expand all
519 519
520 // Once AudioContext::uninitialize() is called there's no more chances for d eleteMarkedNodes() to get called, so we call here. 520 // Once AudioContext::uninitialize() is called there's no more chances for d eleteMarkedNodes() to get called, so we call here.
521 // We can't call in AudioContext::~AudioContext() since it will never be cal led as long as any AudioNode is alive 521 // We can't call in AudioContext::~AudioContext() since it will never be cal led as long as any AudioNode is alive
522 // because AudioNodes keep a reference to the context. 522 // because AudioNodes keep a reference to the context.
523 if (!context()->isInitialized()) 523 if (!context()->isInitialized())
524 context()->deleteMarkedNodes(); 524 context()->deleteMarkedNodes();
525 } 525 }
526 526
527 void AudioNode::breakConnection() 527 void AudioNode::breakConnection()
528 { 528 {
529 // The actual work for deref happens completely within the audio context's
530 // graph lock. In the case of the audio thread, we must use a tryLock to
531 // avoid glitches.
532 bool hasLock = false;
533 bool mustReleaseLock = false;
534
535 if (context()->isAudioThread()) {
536 // Real-time audio thread must not contend lock (to avoid glitches).
537 hasLock = context()->tryLock(mustReleaseLock);
538 } else {
539 context()->lock(mustReleaseLock);
540 hasLock = true;
541 }
542
543 if (hasLock) {
544 breakConnectionWithLock();
545
546 if (mustReleaseLock)
547 context()->unlock();
548 } else {
549 // We were unable to get the lock, so put this in a list to finish up
550 // later.
551 ASSERT(context()->isAudioThread());
552 context()->addDeferredBreakConnection(*this);
553 }
554 }
555
556 void AudioNode::breakConnectionWithLock()
557 {
529 ASSERT(m_normalRefCount > 0); 558 ASSERT(m_normalRefCount > 0);
530 atomicDecrement(&m_connectionRefCount); 559 atomicDecrement(&m_connectionRefCount);
531 m_wasDisconnected = true; 560 if (m_connectionRefCount == 0 && m_normalRefCount > 1)
561 disableOutputsIfNecessary();
532 } 562 }
533 563
534 void AudioNode::finishDeref() 564 void AudioNode::finishDeref()
535 { 565 {
536 ASSERT(context()->isGraphOwner()); 566 ASSERT(context()->isGraphOwner());
537 567
538 ASSERT(m_normalRefCount > 0); 568 ASSERT(m_normalRefCount > 0);
539 atomicDecrement(&m_normalRefCount); 569 atomicDecrement(&m_normalRefCount);
540 570
541 #if DEBUG_AUDIONODE_REFERENCES 571 #if DEBUG_AUDIONODE_REFERENCES
542 fprintf(stderr, "%p: %d: AudioNode::deref() %d %d\n", this, nodeType(), m_no rmalRefCount, m_connectionRefCount); 572 fprintf(stderr, "%p: %d: AudioNode::deref() %d %d\n", this, nodeType(), m_no rmalRefCount, m_connectionRefCount);
543 #endif 573 #endif
544 574
545 if (m_wasDisconnected) {
546 if (m_connectionRefCount == 0 && m_normalRefCount > 0)
547 disableOutputsIfNecessary();
548 m_wasDisconnected = false;
549 }
550
551 if (!m_normalRefCount && !m_isMarkedForDeletion) { 575 if (!m_normalRefCount && !m_isMarkedForDeletion) {
552 // All references are gone - we need to go away. 576 // All references are gone - we need to go away.
553 for (unsigned i = 0; i < m_outputs.size(); ++i) 577 for (unsigned i = 0; i < m_outputs.size(); ++i)
554 output(i)->disconnectAll(); // This will deref() nodes we're connect ed to. 578 output(i)->disconnectAll(); // This will deref() nodes we're connect ed to.
555 579
556 // Mark for deletion at end of each render quantum or when context shuts 580 // Mark for deletion at end of each render quantum or when context shuts
557 // down. 581 // down.
558 context()->markForDeletion(this); 582 context()->markForDeletion(this);
559 m_isMarkedForDeletion = true; 583 m_isMarkedForDeletion = true;
560 } 584 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 // it cannot be reattached. Therefore, the reference count 619 // it cannot be reattached. Therefore, the reference count
596 // will not go above zero again. 620 // will not go above zero again.
597 ASSERT(m_keepAlive); 621 ASSERT(m_keepAlive);
598 m_keepAlive = nullptr; 622 m_keepAlive = nullptr;
599 } 623 }
600 #endif 624 #endif
601 625
602 } // namespace WebCore 626 } // namespace WebCore
603 627
604 #endif // ENABLE(WEB_AUDIO) 628 #endif // ENABLE(WEB_AUDIO)
OLDNEW
« no previous file with comments | « Source/modules/webaudio/AudioNode.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698