Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b3bd0a07 authored by Andy Hung's avatar Andy Hung Committed by Android (Google) Code Review
Browse files

Merge "AudioFlinger: Use atomic pointer for AudioFlinger singleton."

parents e24e6624 6626a01d
Loading
Loading
Loading
Loading
+4 −9
Original line number Diff line number Diff line
@@ -128,9 +128,6 @@ uint32_t AudioFlinger::mScreenState;
// we define a minimum time during which a global effect is considered enabled.
static const nsecs_t kMinGlobalEffectEnabletimeNs = seconds(7200);

Mutex gLock;
wp<AudioFlinger> gAudioFlinger;

// Keep a strong reference to media.log service around forever.
// The service is within our parent process so it can never die in a way that we could observe.
// These two variables are const after initialization.
@@ -268,7 +265,7 @@ void AudioFlinger::onFirstRef()

    mMode = AUDIO_MODE_NORMAL;

    gAudioFlinger = this;
    gAudioFlinger = this;  // we are already refcounted, store into atomic pointer.

    mDevicesFactoryHalCallback = new DevicesFactoryHalCallbackImpl;
    mDevicesFactoryHal->setCallbackOnce(mDevicesFactoryHalCallback);
@@ -325,11 +322,9 @@ status_t MmapStreamInterface::openMmapStream(MmapStreamInterface::stream_directi
                                             sp<MmapStreamInterface>& interface,
                                             audio_port_handle_t *handle)
{
    sp<AudioFlinger> af;
    {
        Mutex::Autolock _l(gLock);
        af = gAudioFlinger.promote();
    }
    // TODO: Use ServiceManager to get IAudioFlinger instead of by atomic pointer.
    // This allows moving oboeservice (AAudio) to a separate process in the future.
    sp<AudioFlinger> af = AudioFlinger::gAudioFlinger.load();  // either nullptr or singleton AF.
    status_t ret = NO_INIT;
    if (af != 0) {
        ret = af->openMmapStream(
+18 −0
Original line number Diff line number Diff line
@@ -306,6 +306,24 @@ private:
    Mutex               mUnregisteredWritersLock;

public:
    // Life cycle of gAudioFlinger and AudioFlinger:
    //
    // AudioFlinger is created once and survives until audioserver crashes
    // irrespective of sp<> and wp<> as it is refcounted by ServiceManager and we
    // don't issue a ServiceManager::tryUnregisterService().
    //
    // gAudioFlinger is an atomic pointer set on AudioFlinger::onFirstRef().
    // After this is set, it is safe to obtain a wp<> or sp<> from it as the
    // underlying object does not go away.
    //
    // Note: For most inner classes, it is acceptable to hold a reference to the outer
    // AudioFlinger instance as creation requires AudioFlinger to exist in the first place.
    //
    // An atomic here ensures underlying writes have completed before setting
    // the pointer. Access by memory_order_seq_cst.
    //

    static inline std::atomic<AudioFlinger *> gAudioFlinger = nullptr;

    class SyncEvent;

+3 −13
Original line number Diff line number Diff line
@@ -2785,11 +2785,7 @@ status_t AudioFlinger::EffectChain::EffectCallback::createEffectHal(
        const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t deviceId,
        sp<EffectHalInterface> *effect) {
    status_t status = NO_INIT;
    sp<AudioFlinger> af = mAudioFlinger.promote();
    if (af == nullptr) {
        return status;
    }
    sp<EffectsFactoryHalInterface> effectsFactory = af->getEffectsFactory();
    sp<EffectsFactoryHalInterface> effectsFactory = mAudioFlinger.getEffectsFactory();
    if (effectsFactory != 0) {
        status = effectsFactory->createEffect(pEffectUuid, sessionId, io(), deviceId, effect);
    }
@@ -2798,19 +2794,13 @@ status_t AudioFlinger::EffectChain::EffectCallback::createEffectHal(

bool AudioFlinger::EffectChain::EffectCallback::updateOrphanEffectChains(
        const sp<AudioFlinger::EffectBase>& effect) {
    sp<AudioFlinger> af = mAudioFlinger.promote();
    if (af == nullptr) {
        return false;
    }
    // in EffectChain context, an EffectBase is always from an EffectModule so static cast is safe
    return af->updateOrphanEffectChains(effect->asEffectModule());
    return mAudioFlinger.updateOrphanEffectChains(effect->asEffectModule());
}

status_t AudioFlinger::EffectChain::EffectCallback::allocateHalBuffer(
        size_t size, sp<EffectBufferHalInterface>* buffer) {
    sp<AudioFlinger> af = mAudioFlinger.promote();
    LOG_ALWAYS_FATAL_IF(af == nullptr, "allocateHalBuffer() could not retrieved audio flinger");
    return af->mEffectsFactoryHal->allocateBuffer(size, buffer);
    return mAudioFlinger.mEffectsFactoryHal->allocateBuffer(size, buffer);
}

status_t AudioFlinger::EffectChain::EffectCallback::addEffectToHal(
+4 −5
Original line number Diff line number Diff line
@@ -524,8 +524,9 @@ private:
        // during construction (but may keep a reference for later promotion).
        EffectCallback(const wp<EffectChain>& owner,
                       const wp<ThreadBase>& thread)
            : mChain(owner) {
            setThread(thread);
            : mChain(owner)
            , mThread(thread)
            , mAudioFlinger(*gAudioFlinger) {
        }

        status_t createEffectHal(const effect_uuid_t *pEffectUuid,
@@ -566,14 +567,12 @@ private:

        void setThread(const wp<ThreadBase>& thread) {
            mThread = thread;
            sp<ThreadBase> p = thread.promote();
            mAudioFlinger = p ? p->mAudioFlinger : nullptr;
        }

    private:
        const wp<EffectChain> mChain;
        mediautils::atomic_wp<ThreadBase> mThread;
        wp<AudioFlinger> mAudioFlinger; // this could be const with some rearrangement.
        AudioFlinger &mAudioFlinger;  // implementation detail: outer instance always exists.
    };

    friend class AudioFlinger;  // for mThread, mEffects