예제 #1
0
void AudioNode::deref(RefType refType)
{
    // The actually work for deref happens completely within the audio context's graph lock.
    // In the case of the audio thread, we must use a tryLock to avoid glitches.
    bool hasLock = false;
    bool mustReleaseLock = false;
    
    if (context()->isAudioThread()) {
        // Real-time audio thread must not contend lock (to avoid glitches).
        hasLock = context()->tryLock(mustReleaseLock);
    } else {
        context()->lock(mustReleaseLock);
        hasLock = true;
    }
    
    if (hasLock) {
        // This is where the real deref work happens.
        finishDeref(refType);

        if (mustReleaseLock)
            context()->unlock();
    } else {
        // We were unable to get the lock, so put this in a list to finish up later.
        ASSERT(context()->isAudioThread());
        context()->addDeferredFinishDeref(this, refType);
    }

    // Once AudioContext::uninitialize() is called there's no more chances for deleteMarkedNodes() to get called, so we call here.
    // We can't call in AudioContext::~AudioContext() since it will never be called as long as any AudioNode is alive
    // because AudioNodes keep a reference to the context.
    if (context()->isAudioThreadFinished())
        context()->deleteMarkedNodes();
}
예제 #2
0
// This method could be called both by the main thread because
// (1) a RefCounted ptr has been deleted or from the audio thread
// because (2) of a disconnect or the deletion of a node that was
// connected to us.
void AudioNode::decrementRefCount(RefType refType) {
  bool hasLock;
  if (!m_context->canUpdateGraph()) {
    m_context->lock();
    hasLock = true;
  } else {
    hasLock = m_context->tryLock();
  }

  if (hasLock) {
    finishDeref(refType);
    m_context->unlock();
  } else {
    assert(m_context->isAudioThread());
    m_context->deferFinishDeref(this);
  }
}