void AudioContext::deleteMarkedNodes()
{
    ASSERT(isGraphOwner() || isAudioThreadFinished());

    // Note: deleting an AudioNode can cause m_nodesToDelete to grow.
    size_t nodesDeleted = 0;
    while (size_t n = m_nodesToDelete.size()) {
        AudioNode* node = m_nodesToDelete[n - 1];
        m_nodesToDelete.removeLast();

        // Before deleting the node, clear out any AudioNodeInputs from m_dirtyAudioNodeInputs.
        unsigned numberOfInputs = node->numberOfInputs();
        for (unsigned i = 0; i < numberOfInputs; ++i)
            m_dirtyAudioNodeInputs.remove(node->input(i));

        // Before deleting the node, clear out any AudioNodeOutputs from m_dirtyAudioNodeOutputs.
        unsigned numberOfOutputs = node->numberOfOutputs();
        for (unsigned i = 0; i < numberOfOutputs; ++i)
            m_dirtyAudioNodeOutputs.remove(node->output(i));

        // Finally, delete it.
        delete node;

        // Don't delete too many nodes per render quantum since we don't want to do too much work in the realtime audio thread.
        if (++nodesDeleted > MaxNodesToDeletePerQuantum)
            break;
    }
}
Example #2
0
bool AudioContext::tryLock(bool& mustReleaseLock)
{
    ThreadIdentifier thisThread = currentThread();
    bool isAudioThread = thisThread == audioThread();

    // Try to catch cases of using try lock on main thread - it should use regular lock.
    ASSERT(isAudioThread || isAudioThreadFinished());
    
    if (!isAudioThread) {
        // In release build treat tryLock() as lock() (since above ASSERT(isAudioThread) never fires) - this is the best we can do.
        lock(mustReleaseLock);
        return true;
    }
    
    bool hasLock;
    
    if (thisThread == m_graphOwnerThread) {
        // Thread already has the lock.
        hasLock = true;
        mustReleaseLock = false;
    } else {
        // Don't already have the lock - try to acquire it.
        hasLock = m_contextGraphMutex.tryLock();
        
        if (hasLock)
            m_graphOwnerThread = thisThread;

        mustReleaseLock = hasLock;
    }
    
    return hasLock;
}
Example #3
0
void AudioContext::derefUnfinishedSourceNodes()
{
    ASSERT(isMainThread() && isAudioThreadFinished());
    for (unsigned i = 0; i < m_referencedNodes.size(); ++i)
        m_referencedNodes[i]->deref(AudioNode::RefTypeConnection);

    m_referencedNodes.clear();
}
Example #4
0
void AudioContext::derefUnfinishedSourceNodes()
{
    ASSERT(isMainThread() && isAudioThreadFinished());
    for (auto& node : m_referencedNodes)
        node->deref(AudioNode::RefTypeConnection);

    m_referencedNodes.clear();
}
Example #5
0
void AudioContext::derefFinishedSourceNodes()
{
    ASSERT(isGraphOwner());
    ASSERT(isAudioThread() || isAudioThreadFinished());
    for (unsigned i = 0; i < m_finishedNodes.size(); i++)
        derefNode(m_finishedNodes[i]);

    m_finishedNodes.clear();
}
Example #6
0
void AudioContext::derefFinishedSourceNodes()
{
    ASSERT(isGraphOwner());
    ASSERT(isAudioThread() || isAudioThreadFinished());
    for (auto& node : m_finishedNodes)
        derefNode(node);

    m_finishedNodes.clear();
}
Example #7
0
void AudioContext::markForDeletion(AudioNode* node)
{
    ASSERT(isGraphOwner());

    if (isAudioThreadFinished())
        m_nodesToDelete.append(node);
    else
        m_nodesMarkedForDeletion.append(node);

    // This is probably the best time for us to remove the node from automatic pull list,
    // since all connections are gone and we hold the graph lock. Then when handlePostRenderTasks()
    // gets a chance to schedule the deletion work, updateAutomaticPullNodes() also gets a chance to
    // modify m_renderingAutomaticPullNodes.
    removeAutomaticPullNode(node);
}
Example #8
0
void AudioContext::deleteMarkedNodes()
{
    ASSERT(isGraphOwner() || isAudioThreadFinished());

    // Note: deleting an AudioNode can cause m_nodesToDelete to grow.
    size_t nodesDeleted = 0;
    while (size_t n = m_nodesToDelete.size()) {
        AudioNode* node = m_nodesToDelete[n - 1];
        m_nodesToDelete.removeLast();
        delete node;

        // Don't delete too many nodes per render quantum since we don't want to do too much work in the realtime audio thread.
        if (++nodesDeleted > MaxNodesToDeletePerQuantum)
            break;
    }
}